删除每月的前几天-PHP Array

时间:2018-12-17 19:09:29

标签: php arrays

我有一个数组,其中包含有关一个月内完成的所有工作日/工作的信息。一个月可以有多个工作日。所以我的数组看起来像这样(在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));

问题在于,结果是它删除了LAST,而不是第一个日期,并将其添加为键。这是输出:

"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
},

希望有人可以告诉我如何进行。谢谢!

6 个答案:

答案 0 :(得分:5)

您可以只查看循环中的时间。然后,您不必担心输入数据是否已排序。

$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}
}

Demo on 3v4l.org

答案 1 :(得分:1)

您可以仅在时间字段中对数据进行排序,然后再在主循环中提取数据。我用spaceship operator <=>比较了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));

答案 2 :(得分:1)

这是因为您的关联数组索引与其他数组索引相同,所以它正在替换值。您可以如下调整代码。 如果您想要确切的显示方式,请告诉我。

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

答案 3 :(得分:1)

只需使用一个条件:

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

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

答案 4 :(得分: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,但只要您想要的话就对其进行编码。

答案 5 :(得分: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
}