Reputation: 9833
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.
Upvotes: 0
Views: 236
Reputation: 6092
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.
Upvotes: 3
Reputation: 464
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);
Upvotes: 0
Reputation: 11859
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);
Upvotes: 0