Удалить предыдущие дни месяца — PHP Array

У меня есть массив, в котором есть информация обо всех рабочих днях / работах, которые выполняются за месяц. Месяц может иметь несколько дней, которые были рабочим днем. Итак, мой массив выглядит так (в формате JSON):

{
"id": 1,
"time": "2018-12-16",
"pages_indexed": 1024
},
{
"id": 2,
"time": "2018-12-12",
"something": 1024
},
{
"id": 3,
"time": "2018-12-09",
"something": 7
},

(....)

{
"id": 12,
"time": "2018-11-12",
"something": 7
},
{
"id": 13,
"time": "2018-11-08",
"something": 7
}

Затем я попробовал это:

$expectedArray = [];
foreach ($items as $item) {
$indexKey = substr($item['time'], 0, 7);
$expectedArray[$indexKey] = $item;
}
print_r(json_encode($expectedArray));

Проблема в том, что в результате он удаляет последние, а не первые даты и добавляет их в качестве ключа. Это вывод:

"2018-12": {
"id": 123456,
"time": "2018-12-09",
"something": 1029
},
"2018-11": {
"id": 123456,
"time": "2018-11-08",
"something": 1032
},

Это первые дни в списке того же месяца. Я хотел бы и ожидать, что результат будет:

"2018-12": {
"id": 123456,
"time": "2018-12-16",
"something": 1029
},
"2018-11": {
"id": 123456,
"time": "2018-11-12",
"something": 1032
},

Надеюсь, кто-то может показать мне, как я могу действовать. Спасибо!

3

Решение

Вы можете просто проверить время в вашем цикле, когда вы проходите через него. Тогда вам не нужно беспокоиться о том, отсортированы ли входные данные.

$expectedArray = [];
foreach ($items as $item) {
$indexKey = substr($item['time'], 0, 7);
if (!isset($expectedArray[$indexKey]) || $expectedArray[$indexKey]['time'] < $item['time'])
$expectedArray[$indexKey] = $item;
}
print_r(json_encode($expectedArray));

Вывод (для ваших образцов данных):

{"2018-12":
{"id":1,"time":"2018-12-16","pages_indexed":1024},
"2018-11":
{"id":12,"time":"2018-11-12","something":7}
}

Демо на 3v4l.org

5

Другие решения

Вы можете просто отсортировать данные по временному полю перед извлечением данных в вашем основном цикле. Я использовал оператор космического корабля <=> сравнить даты, которые PHP 7 + …

usort($items, function ($a, $b) {
return $a['time'] <=> $b['time'];
});
$expectedArray = [];
foreach ($items as $item) {
$indexKey = substr($item['time'], 0, 7);
$expectedArray[$indexKey] = $item;
}
print_r(json_encode($expectedArray));
1

Это потому, что ваш индекс ассоциативного массива совпадает с другим, поэтому он заменяет значения. Вы можете настроить свой код, как показано ниже.
Если вы хотите точно, как вы показали, дайте мне знать.

    $expectedArray = [];
foreach ($items as $item) {
$indexKey = substr($item['time'], 0, 7);
$expectedArray[$indexKey][] = $item;
}
print_r(json_encode($expectedArray));
1

Просто используйте условие:

foreach ($items as $item) {
$indexKey = substr($item['time'], 0, 7);

if (!isset($expectedArray[$indexKey]) || ( && ($item['time'] > $expectedArray[$indexKey]['time'])) {
$expectedArray[$indexKey] = $item;
}
}
1

Зациклите цикл в обратном направлении и добавьте его в ассоциативный массив с Y-m.
Из-за этого этот метод не нуждается в какой-либо логике.

$arr = json_decode($str, true);
$time = array_column($arr, "time"); // for sorting
array_multisort($time, SORT_ASC, $arr); //sort array.

foreach($arr as $sub){
$result[substr($sub["time"], 0, 7)]= $sub;
}

var_dump($result);

Код будет сначала добавлять самое старое значение, а затем перезаписывать более новым значением каждый раз, когда появляется один и тот же месяц.
Конечный результат — новейшие значения каждого месяца.

Выход:

array(2) {
["2018-11"]=>
array(3) {
["id"]=>
int(12)
["time"]=>
string(10) "2018-11-12"["something"]=>
int(7)
}
["2018-12"]=>
array(3) {
["id"]=>
int(1)
["time"]=>
string(10) "2018-12-16"["pages_indexed"]=>
int(1024)
}
}

https://3v4l.org/RhiO9

Я не включил json_encode, а просто закодировал его, если это то, что вы хотите.

1

Это потому, что вы дублируете ключ для массива, и он заканчивается последним, установленным для этого месяца.
Если вам нужен только первый, вы должны включать флаг для каждого месяца, или вам нужно будет создать другой массив, отсортировать его, а затем взять первый.

$expectedArray = [];

foreach ($items as $item) {
$indexKey = substr($item['time'], 0, 7);
$expectedArray[$indexKey] .= $item.",";
}

$expectedArray_final = [];
foreach($expectedArray as  $expectedIndex=> $expectedValue){
$ar= explode(",", $expectedValue);
asort($ar);
$expectedArray_final[$expectedIndex]=$ar[0];//the first element sorted is the first day of the month
}
1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector