массив объектов выбор объекта на основе значения атрибута


В данный момент я работаю с API Mailchimp, у меня есть список кампаний, которые были запущены или должны быть запущены, и я хочу получить ссылку на самую последнюю запущенную кампанию. Как бы я сравнил атрибут "send_time", чтобы найти самый последний и приписываемый ему родительский объект?

Массив campaigns выглядит следующим образом,

{
    "campaigns": [
        {
            "id": 1,
            "type": "regular",
            "status": "save",
            "send_time": ""
        },
        {
            "id": 2,
            "type": "regular",
            "status": "sent",
            "send_time": "2015-11-11T14:42:58+00:00"
        },
        {
            "id": 3,
            "type": "regular",
            "status": "sent",
            "send_time": "2016-01-01T14:42:58+00:00"
        },
        {
            "id": 4,
            "type": "regular",
            "status": "sent",
            "send_time": "2016-06-12T14:42:58+00:00"
        }
    ]
}

Итак, в этом вышеприведенном массиве конечный объект имеет самый последний send_time, как бы я оценил это, а затем схватил это объект? У меня есть полурешение, но оно кажется слишком затянутым.

<?php
    //Build an array of send_times
    $dates = [];
    foreach($result['campaigns'] as $campaign) {
        $dates[$campaign['id']] = $campaign['send_time'];
    }

    //Get the most recent date
    $mostRecent = 0;
    foreach($dates as $k => $v) {
        $curDate = strtotime($v);
        if($curDate > $mostRecent) {
           $mostRecent = $curDate
           $currentId = $k;
        }
    }

    //Get the object
    foreach($results['campaigns'] as $campaign) {
         if($campaign['id'] == $currentId) {
             $c = $campaign;
         }
    }
?>
4 2

4 ответа:

Используйте array_multisort() как показано ниже (однострочный код): -

<?php    
$data = '{
    "campaigns": [
        {
            "id": 1,
            "type": "regular",
            "status": "save",
            "send_time": ""
        },
        {
            "id": 2,
            "type": "regular",
            "status": "sent",
            "send_time": "2015-11-11T14:42:58+00:00"
        },
        {
            "id": 3,
            "type": "regular",
            "status": "sent",
            "send_time": "2016-01-01T14:42:58+00:00"
        },
        {
            "id": 4,
            "type": "regular",
            "status": "sent",
            "send_time": "2016-06-12T14:42:58+00:00"
        }
    ]
}';
$array = json_decode($data,true)['campaigns']; // decode json string to array  
array_multisort($array,SORT_DESC, SORT_STRING); // use of array_multisort
echo "<pre/>";print_r($array); // this will returns you indexed array like 0,1,2... you can again convert it to campaigns array like $final_array['campaigns'] = $array;
?>

Вывод: - https://eval.in/598349

Примечание:-

1.Если ваши данные уже находятся в массиве, то нет необходимости использовать json_decode(), непосредственно используйте array_multisort() на нем

Https://eval.in/598355

Для более подробной справки: -

Http://sg2.php.net/manual/en/function.array-multisort.php

<?php
    $dates = [];
    $recent_campaign = null;
    $recent_time = 0;
    foreach($result['campaigns'] as $campaign) {
        $curDate = strtotime($campaign['send_time']);
        if($curDate > $recent_time) {
            $recent_time = $curDate
            $recent_campaign = $campaign;
        }
    }
    //$recent_campaign is the most recent campaign 
?>

Вы можете попробовать этот подход. В противном случае вы можете использовать usort по send_time (прямое решение).

Я не выполнил этот код!

Вы можете сортировать объекты по этому свойству (я бы предложил usort, чтобы вы могли определить свою собственную сортировку), а затем получить первый элемент в этом массиве.

usort($result, function ($campaign1, $campaign2) {
    if ($campaign1['send_time'] == $campaign2['send_time']) {
        return 0;
    }

    return (strtotime($campaign1['send_time']) > strtotime($campaign2['send_time'])) ? -1 : 1;
});

$mostRecentCampaign = $campaign[0];

Примечание : я не запускал это, поэтому вам, возможно, придется настроить return на функцию сравнения, если она сортирует в неправильном порядке.

Если вы просто хотите захватить элемент max и хотите использовать меньше строк кода, попробуйте сделать следующее:

  1. захватите максимальное время, сопоставив столбец "время отправки" с временем эпохи и получив максимальное значение
  2. фильтруйте массив по записям, соответствующим этому максимальному времени
  3. прибыль

Пример:

$dataArray = /* your array */
$maxTime =  max(array_map('strtotime',array_column($dataArray["campaigns"], 'send_time')));
$maxEntry = array_filter($dataArray["campaigns"], function ($arr) use ($maxTime) { return strtotime($arr["send_time"])==$maxTime; });
print_r($maxEntry);

Напечатает:

Array
(
    [3] => Array
        (
            [id] => 4
            [type] => regular
            [status] => sent
            [send_time] => 2016-06-12T14:42:58+00:00
        )

)

Примечание преимущество этого состоит в том, что он не нуждается в сортировке. Недостатком является то, что сортировка, а затем получение последний элемент будет быстрее. Однако при сортировке вы теряете исходный порядок массива, который иногда необходим.