Reputation: 45
I want to get the minimum date from the date column of a multidimensional array, but only from rows with keycode
of 0001
.
How would I achieve that?
$a = [
"a" => ['keycode' => '0001','date' => "2015-09-08"],
"b" => ['keycode' => '0002','date' => "2015-09-05"],
"c" => ['keycode' => '0003','date' => "2015-09-04"],
"d" => ['keycode' => '0001','date' => "2015-09-01"],
"e" => ['keycode' => '0001','date' => "2015-08-01"]
];
Expected result: 2015-08-01
Upvotes: 0
Views: 1175
Reputation: 47934
Because your date expression are already in Y-m-d
, they are instantly comparable as simple strings. This means that there is no need to call strtotime()
for any part of this task.
If you prefer usort()
, you can sort on two criteria. The following snippet will first sort on the keycode
and put all 0001
rows at the front and everything else toward the back of the array. When a tiebreak is required, the second sorting rule is to compare the dates ASC.
When finished, the first occurring row will either be the 0001
row with the smallest date value or it won't be a 0001
row because there weren't any in the input array.
Code: (Demo)
$array = [
"a" => ['keycode' => '0001','date' => "2015-09-08"],
"b" => ['keycode' => '0002','date' => "2015-09-05"],
"c" => ['keycode' => '0003','date' => "2002-12-04"],
"d" => ['keycode' => '0001','date' => "2015-09-01"],
"e" => ['keycode' => '0001','date' => "2015-10-01"]
];
$needle = '0001';
usort($array, fn($a, $b) => [$a['keycode'] !== $needle, $a['date']] <=> [$b['keycode'] !== $needle, $b['date']]);
echo $array[0]['keycode'] === $needle ? $array[0]['date'] : "No qualifying rows for $needle";
// 2015-09-01
If you'd rather see a classic loop, then this approach will conditionally update a temporary variable. (Demo)
$needle = '0001';
$earliest = null;
foreach ($array as $row) {
if ($row['keycode'] === $needle && (!$earliest || $row['date'] < $earliest)) {
$earliest = $row['date'];
}
}
echo $earliest ?? "No qualifying rows for $needle"; // 2015-09-01
Upvotes: 0
Reputation: 2985
If the array is already sorted and you are using php 5.5.0+, then you can try this
$arr = array_column($a, "date", "keycode");
echo $arr["0001"] // string(10) "2015-08-01"
Upvotes: 0
Reputation: 6381
You can do this with a combination of array_filter and uasort:
function getMinDateByKeycode(array $a, $keycode)
{
// Filter out elements by keycode
$aFiltered = array_filter($a, function($aItem) use ($keycode) {
return $aItem['keycode'] === $keycode;
});
// Sort lowest date first
uasort($aFiltered, function($a1, $a2){
return strtotime($a1['date']) - strtotime($a2['date']);
});
// Get the key of the first element of the resulting array
reset($aFiltered);
$keyOfMinDate = key($aFiltered);
// Return it however you want. This example returns just the date.
return $a[$keyOfMinDate]['date'];
}
echo getMinDateByKeycode($a, '0001');
// prints '2015-08-01'
Upvotes: 1
Reputation: 4783
I would first extract all of the values that have a keycode of 0001 and create a new array of just those dates. Then use the php min()
function.
$a=array(
"a" => array('keycode' => '0001','date' =>"2015-09-08"),
"b" => array('keycode' => '0002','date' =>"2015-09-05"),
"c" => array('keycode' => '0003','date' =>"2015-09-04"),
"d" => array('keycode' => '0001','date' =>"2015-09-01"),
"e" => array('keycode' => '0001','date' =>"2015-08-01")
);
$b = [];
foreach($a as $key => $value){
if($value['keycode']=='0001'){
$b[]=$value['date'];
}
}
print_r($b);
echo min($b);
Upvotes: 1
Reputation: 3124
This will work:
function min_date($a){
$dates = [];
foreach($a as $key => $value){
if($value['keycode']=='0001'){
array_push($dates,strtotime($value['date']));
}
}
return date("Y/m/d",min($dates));
}
$result = min_date($a);
Upvotes: 1