LexxTal
LexxTal

Reputation: 59

Compare PHP array value to PART of a string

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

Answers (4)

blasko
blasko

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

Ethan22
Ethan22

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

Nick Coons
Nick Coons

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

scrowler
scrowler

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);

Example here.

Upvotes: 3

Related Questions