返回基于最近日期和其他值的多维数组值


Return multidimensional array value based on most recent date and another value

我的代码基于以下链接:PHP多维数组搜索(按特定值查找关键字)我试图添加类似于从日期数组中获取最近日期的代码;然而,我不断收到非法的偏移错误。

我可以根据第一个代码成功地选择合适的值。然后,我如何根据数组中的最近日期缩小我的报税表?

我使用的是php5.4.45,我的数组总是按日期排序,最近的是最后一个。我不能简单地选择最后一个数组索引,因为它并不总是"已支付"订单状态。

我的阵列:

array(4) { 
[0]=> array(3) { 
    ["status"]=> string(6) "Active" 
    ["check_number"]=> string(0) "" 
    ["date_added"]=> string(19) "17/11/2015 10:34:53" } 
[1]=> array(3) { 
    ["status"]=> string(4) "Paid" 
    ["check_number"]=> string(5) "12345" 
    ["date_added"]=> string(19) "14/12/2015 07:40:59" } 
[2]=> array(3) { 
    ["status"]=> string(8) "Invoiced" 
    ["check_number"]=> string(0) ""  
    ["date_added"]=> string(19) "14/12/2015 09:44:31" } 
[3]=> array(3) { 
    ["status"]=> string(4) "Paid" 
    ["check_number"]=> string(4) "0258" 
    ["date_added"]=> string(19) "14/12/2015 09:53:29" } 
} 

我的代码:

function getValue($fromSource, $field, $value, $get){
    if ($fromSource[$field] === $value) {
        return $fromSource[$get];
    };
    return false;
}
foreach ($order['order_history'] as $order_history) {
    var_dump(getValue($order_history, "status", "Paid", "check_number"));
}

期望结果:"0258"(其中状态="已支付",日期=最近)

当前接收:"12345"0258"(其中status="已支付")

使用array_walk收集所有日期。

我们使用createFromFormatgetTimestamp将日期转换为时间戳,这样我们就可以很容易地对它们进行排序,而不会忘记传递timezone

我们获得最高时间戳的密钥,并使用它来访问项目列表。

CCD_ 5是初始阵列。

$dates = array();
$format = 'd/m/Y H:i:s';
$timezone = new DateTimeZone('UTC'); 
array_walk($items,function($item,$index) use(&$dates,$format,$timezone){
    $date = DateTime::createFromFormat($format, $item["date_added"],$timezone);
    $dates[$index] = $date->getTimestamp();
});
// get the key of the most recent date
$key = array_keys($dates, max($dates))[0];
// using the key get the item from the list
print_r($items[$key]) . PHP_EOL;

将输出

Array
(
    [status] => Paid
    [check_number] => 0258
    [date_added] => 14/12/2015 09:53:29
)

从这里你可以很容易地访问结果的一个元素

print $items[$key]["check_number"];

将输出

0258

我认为另一种可能性是用foreach构造循环您的数组,并检查迭代中的每个数组是否"status"为"Payed"。然后,每次迭代都可以使用DateTime对象将当前$item中的日期与$result数组中的日期进行比较。

例如:

$items = array(
    array(
        "status" => "Active",
        "check_number" => "",
        "date_added" => "17/11/2015 10:34:53"
    ),
    array(
        "status" => "Paid",
        "check_number" => "12345",
        "date_added" => "14/12/2015 07:40:59"
    ),
    array(
        "status" => "Invoiced",
        "check_number" => "",
        "date_added" => "14/12/2015 09:44:31"
    ),
    array(
        "status" => "Paid",
        "check_number" => "0258",
        "date_added" => "14/12/2015 09:53:29"
    )
);
$result = array();
foreach ($items as $item) {
    if ($item["status"] === "Paid") {
        // If there is no result yet with status "Paid", then add it.
        if (count($result) === 0) {
            $result = $item;
            continue;
        }
        $itemDateTime = DateTime::createFromFormat('d/m/Y H:i:s', $item["date_added"]);
        $resultDateTime = DateTime::createFromFormat('d/m/Y H:i:s', $result["date_added"]);
        if ($itemDateTime > $resultDateTime) {
            $result = $item;
        }
    }
}
var_dump($result);

将导致:

array (size=3)
  'status' => string 'Paid' (length=4)
  'check_number' => string '0258' (length=4)
  'date_added' => string '14/12/2015 09:53:29' (length=19)

然后,您可以从$result数组中访问您的值,如下所示:

echo $result["check_number"];

将导致:

0258

演示

如果数组总是排序的,您可以使用此代码来获得与相应状态匹配的最新条目:

    function getLatest($arr, $field, $value, $getField){
        for($i=count($arr)-1;$i >= 0; $i--){
                $currSubArr = $arr[$i];
                if($currSubArr[$field] === $value){
                    return $currSubArr[$getField];
                }   
        }
    }
    $orders[] = array('status' => 'active', 'checknumber'=> '121234','date_added' => '17/11/2015 10:34:53');
    $orders[] = array('status' => 'paid', 'checknumber' => '1212334','date_added' => '17/11/2015 10:38:53');
    $orders[] = array('status' => 'paid', 'checknumber '=> '5234','date_added' => '17/11/2015 10:42:53');

  //test --> returns 5234 
    echo getLatest($orders,'status','paid','checknumber');