Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search in PHP array with a custom comparator

Tags:

php

search

This is probably hopeless but still, is there a way to search for elements in an array with my own comparator function? Implementing it in PHP would result in slow searches, so maybe a better solution exists?

What I actually want from the search is a) get to know whether the element is present in the array and b) preferably, get the key (index) of the found element.

For example

$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

and if the comparator would look like this

$comp = function ($arrValue, $findValue) {
    return ($arrValue % $findValue) == 0;
};

Then the comparator-based search function would return true if 8 was searched and, which would be nice of it, output the index of the found element, which is 7.

like image 310
Desmond Hume Avatar asked Jun 08 '14 12:06

Desmond Hume


1 Answers

You mean something like:

$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$findValue = 8;

$result = array_filter(
    $arr, 
    function ($arrValue) use($findValue) {
        return ($arrValue % $findValue) == 0;
    }
);

EDIT

Perhaps you mean something more like:

$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
$findValue = 3;

foreach(array_filter(
    $arr, 
    function ($arrValue) use($findValue) {
        return ($arrValue % $findValue) == 0;
    }
) as $key => $value) {
    echo $value, ' is a multiple of ', $findValue, PHP_EOL;
}

EDIT #2

Or do you mean something a lot more sophisticated like:

function filter($values, $function) {
    return array_filter(
        $values,
        $function
    );
}

$isEven = function ($value) {
    return !($value & 1);
};

$isOdd = function ($value) {
    return $value & 1;
};

$data = range(1,10);

echo 'array_filter() for Odds', PHP_EOL;
var_dump(
    filter(
        $data,
        $isOdd
    )
);

echo 'array_filter() for Evens', PHP_EOL;
var_dump(
    filter(
        $data,
        $isEven
    )
);

or using PHP 5.5 Generators as well:

$isEven = function ($value) {
    return !($value & 1);
};

$isOdd = function ($value) {
    return $value & 1;
};

function xFilter(callable $callback, $args=array()) {
    foreach($args as $arg) {
        if (call_user_func($callback, $arg)) {
            yield $arg;
        }
    }
}

echo 'xFilter for Odds', PHP_EOL;
foreach(xFilter($isOdd, range(1,10)) as $i) {
    echo('num is: '.$i.PHP_EOL);
}

echo 'xFilter for Evens', PHP_EOL;
foreach(xFilter($isEven, range(1,10)) as $i) {
    echo('num is: '.$i.PHP_EOL);
}
like image 168
Mark Baker Avatar answered Sep 27 '22 22:09

Mark Baker