0

For an array such as:

$array = array(
    735 => array('name'=>'Alpha', 'num'=>1),
    584 => array('name'=>'Beta', 'num'=>4),
    857 => array('name'=>'Gamma', 'num'=>1),
    982 => array('name'=>'Delta', 'num'=>2)
);

what would be the best way to filter elements with least value of num. That is, in this case, the solution would be the following array:

array(
    735 => array('name'=>'Alpha', 'num'=>1),
    857 => array('name'=>'Gamma', 'num'=>1)
);

I'm aware that this can be done via a foreach loop and keeping track of the least value but I was hoping there would be some array function which would do the job.

My current approach is:

$num_values = array();
foreach($array as $id => $meta)
{
    $num_values[] = $meta['num'];
}
$min_num_value = min($num_values);

$filtered_array = array();
foreach($array as $id => $meta)
{
    if($meta['num'] == $min_num_value)
    {
        $filtered_array[$id] = $meta;
    }
}
print_r($filtered_array);

which, as you can see, is clearly not the best way to go about the task.

0

3 Answers 3

3

Optimized version of filtering with minimum value calculation and O(n) complexity.

$array = array(
    735 => array('name'=>'Alpha', 'num'=>1),
    584 => array('name'=>'Beta', 'num'=>4),
    857 => array('name'=>'Gamma', 'num'=>1),
    982 => array('name'=>'Delta', 'num'=>2)
);

$minValue      = PHP_INT_MAX;
$filteredArray = [];
foreach ($array as $key=>$data) {
    $itemNumber = $data['num'];
    if ($itemNumber < $minValue) {
        $filteredArray = [$key => $data];
        $minValue      = $itemNumber;
    } elseif ($itemNumber === $minValue) {
        $filteredArray[$key] = $data;
    }
}

var_dump($filteredArray);

Performance of foreach is better than any array_xxx() functions plus invocation of closures/functions. So, this solution must be efficient even for big arrays.

Sign up to request clarification or add additional context in comments.

3 Comments

Confirm. Microbenchmark shows me ~50% boost (as compared with two loops) for large (5M rows) dataset.
I see something that I've never seen before [$key => $data]. Is that PHP7 syntax?
Short array syntax, available since PHP 5.4
0

Since min gives only one record you can try like this: It will remove first foreach loop, rest is yours.

$array = array(
        735 => array('name'=>'Alpha', 'num'=>1),
        584 => array('name'=>'Beta', 'num'=>4),
        857 => array('name'=>'Gamma', 'num'=>1),
        982 => array('name'=>'Delta', 'num'=>2)
);
$val = min($array);
$filtered_array=array();
foreach($array as $id => $meta)
{
    if($meta['num'] == $val['num'])
    {
        $filtered_array[$id] = $meta;
    }
}
print_r($filtered_array);

1 Comment

min($array) - It's taking the lowest index value, i.e. 584.. whereas I want the min value of num
0

this might be help you

$arr = array(
    735 => array('name'=>'Alpha', 'num'=>1),
    584 => array('name'=>'Beta', 'num'=>4),
    857 => array('name'=>'Gamma', 'num'=>1),
    982 => array('name'=>'Delta', 'num'=>2)
);

$inventory = array_map("array_values", $arr);
usort($inventory, function ($item1, $item2) {
    if ($item1[1] == $item2[1]) return 0;
    return $item1[1] < $item2[1] ? -1 : 1;
});

echo "<pre>";print_r($inventory);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.