Reputation: 59
I'm trying to automate sifting through my online bank statements. Here's a trivial example of what I need.
I have an array of restaurants against which I sort my credit card statements:
$restaurants = array(
array("vendor" => "default",
"type" => "default"
),
array("vendor" => "dunkin",
"type" => "pastry"
),
array("vendor" => "mcdonald",
"type" => "fastfood"
),
array("vendor" => "olive",
"type" => "italian"
)
);
The statement entries themselves can be a rather descriptive string:
$string = "McDonald's Restaurants Incorporated";
I've tried using array_search and in_array, but they seem to do the reverse of what I need, or they need an exact match like in the example below, but it is not what I need:
$result = array_search($string, array_column($restaurants, 'vendor'));
return $restaurants[$result]['type'];
// returns "default" because "McDonald's Restaurants Incorporated" != "mcdonald"
I would like to be able to match the array value "mcdonald" to any string that contains that chunk of it, and then return type "fastfood" for it. Don't worry about handling multiple occurrences.
Upvotes: 2
Views: 74
Reputation: 690
I took a different (functional) approach by using array_map and array_filter. It's rather compact due to the use of builtin functions, and gets the job done.
// 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));
Upvotes: 0
Reputation: 747
I got fixated on the in_array portion of the question. Editing this to use strpos instead.
Try this:
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
Upvotes: -1
Reputation: 3692
I don't think there's a function in PHP that will handle this quite as cleanly as you want. But you can whip up a quick function to loop through the array looking for matches:
$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 );
If $string
is "McDonald's Restaurants Incorporated", then $type
will be "fastfood". The above makes the assumption that the first instance in the array is your default return if none of the specified values match.
I just built this as an anonymous function/closure out of convenience, which I usually would to do cleanly enclose something I only plan to run once. But it may be cleaner as a named function in your application.
Upvotes: 2
Reputation: 24406
You'll need a combination of things - a search-in-string method, and for it to be case insensitive.
You can accomplish this with something like this:
/**
* 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;
}
And use it like so:
$result = findRoughly("McDonald's", $restaurants);
Upvotes: 3