2015-07-29 2 views
2

Я пытаюсь автоматизировать просеивание через свои банковские выписки. Вот тривиальный пример того, что мне нужно.Сравните значение массива PHP с PART строки

У меня есть множество ресторанов, против которых я сортирую мои заявления кредитной карты:

$restaurants = array(
    array("vendor" => "default", 
      "type" => "default" 
    ), 
    array("vendor" => "dunkin", 
      "type" => "pastry" 
    ), 
    array("vendor" => "mcdonald", 
      "type" => "fastfood" 
    ), 
    array("vendor" => "olive", 
      "type" => "italian" 
    ) 
); 

Оператор Запись сам может быть довольно описательная строка:

$string = "McDonald's Restaurants Incorporated"; 

Я попытался с помощью array_search и in_array, но они, похоже, обращают внимание на то, что мне нужно, или им нужно точное соответствие , как в примере ниже, но это не то, что мне нужно:

$result = array_search($string, array_column($restaurants, 'vendor')); 
return $restaurants[$result]['type']; 

// returns "default" because "McDonald's Restaurants Incorporated" != "mcdonald" 

Я хотел бы быть в состоянии соответствовать значению массива «Макдоналдс» на любую строку, которая содержит этот кусок, а потом вернуться типом «фастфуд» для него. Не беспокойтесь о том, чтобы обрабатывать несколько случаев.

ответ

2

Вам нужно сочетание вещей - a search-in-string method, and for it to be case insensitive.

Вы можете сделать это с чем-то вроде этого:

/** 
* Perform a string-in-string match case insensitively 
* @param string $string 
* @param array $restaurants 
* @return string|false 
*/ 
function findRoughly($string, $restaurants) 
{ 
    $out = false; 
    foreach ($restaurants as $restaurant) { 
     // Set up the default value 
     if ($restaurant['type'] == 'default' && !$out) { 
      $out = $restaurant['type']; 
      // Stop this repetition only 
      continue; 
     } 
     // Look for a match 
     if (stripos($string, $restaurant['vendor']) !== false) { 
      $out = $restaurant['type']; 
      // Match found, stop looking 
      break; 
     } 
    } 
    return $out; 
} 

И использовать его так:

$result = findRoughly("McDonald's", $restaurants); 

Example here.

+0

Работает правильно! Спасибо за пример кода, который очень ценится. – LexxTal

+0

Это можно сделать более эффективно. Почему вы используете временную переменную $ out?Почему бы не вернуть $ restaurant ['type'], как только он будет найден, и иметь оператор возврата по умолчанию за пределами цикла? Это сократит вашу функцию до 9 строк, не считая комментарии. – blasko

+0

Привет @blasko, временная переменная предназначена для обработки ситуации, когда значение по умолчанию может быть не в начале массива, а, возможно, в середине или в конце. Если ни совпадение не установлено по умолчанию, верните значение false –

-1

Я был зафиксирован на части вопроса in_array. Редактируем это, чтобы вместо этого использовать strpos.

Попробуйте это:

foreach($restaurants as $restaurant) 
{ 
    if(strpos($restaurant['vendor'], $string) !== FALSE) 
    { 
      return $restaurant['type']; //Or add to an array/do whatever you want with this value. 
    } 
} 

http://php.net/manual/en/function.strpos.php

+1

Второй параметр in_array() не может быть строкой. – LexxTal

2

Я не думаю, что есть функция в PHP, который будет обрабатывайте это так же чисто, как вы хотите. Но вы можете подстегнуть функцию быстрой Переберите массив в поисках совпадений:

$type = call_user_func(function($restaurants, $string) { 
    foreach ($restaurants as $restaurant) { 
     if (stripos($string, $restaurant['vendor']) !== FALSE) { 
      return $restaurant['type']; 
     } 
    } 

    return $restaurant[0]['type']; 
}, $restaurants, $string); 

Если $string является «Макдональдс Ресторанов Инкорпорейтед», то $type будет «фастфуд». Вышеприведенное предположение о том, что первый экземпляр массива является вашим возвратом по умолчанию, если ни одно из указанных значений не совпадает.

Я только что построил это как анонимную функцию/закрытие из удобства, которое я обычно делал, чтобы чисто заключить что-то, что я планирую только запустить. Но он может быть более чистым, как именованная функция в вашем приложении.

+0

Спасибо за ответ. Он также хорошо работает, приветствует. – LexxTal

0

Я использовал другой (функциональный) подход, используя array_map и array_filter. Это довольно компактно из-за использования встроенных функций и выполняет свою работу.

// Anonymous function which gets passed to array_map as a callback 
// Checks whether or not the vendor is in the $key_string (your restaurant) 
$cmp = function ($array) use ($key_string) { 
    if (stristr($key_string, $array['vendor'])) { 
     return $array['type']; 
    } 
    return "default"; 
}; 

function validResult($item) { 
    return isset($item) && gettype($item)=="string"; 
} 

$key_string = "McDonald's Restaurants Incorporated"; 
$results = array_map($cmp, $restaurants); 
$results = array_pop(array_filter($results, validResult)); 
Смежные вопросы