通过键值对数组项进行分组,并添加具有分组值的键

时间:2018-11-28 16:19:58

标签: php arrays

具有以下数组:

$a = array("category" => "Music", 
        "items" => array(
            array("ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"),
            array("ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"),
            array("ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30"),
            array("ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"),
            array("ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31")
        )
);

echo "<pre>";
print_r($b);
echo "</pre>";

我想通过end_date对数组进行“分组”,但不像我在其他posts或{{3}中看到的那样,使用end_date作为键对进行分组},但是将end_date的值添加为新键的值。

以使预期结果为:

$b = array("category" => "Music",
        "items" => array(
            array("date" => "2018-11-28",
                array("ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"),
                array("ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"),
            ),
            array("date" => "2018-11-30",
                array("ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30")
            ),
            array("date" => "2018-11-31",
                array("ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"),
                array("ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31")
            )
        )
);


echo "<pre>";
print_r($b);
echo "</pre>";

2 个答案:

答案 0 :(得分:2)

对数组进行循环,并以结束日期为键构建一个临时的关联数组。
然后复制原始数组并取消设置“项目”,然后添加新的临时数组值。

$a = array("category" => "Music", 
        "items" => array(
            array("ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"),
            array("ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"),
            array("ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30"),
            array("ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"),
            array("ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31")
        )
);

foreach($a['items'] as $item){
    $new[$item['end_date']]['date'] = $item['end_date'];
    $new[$item['end_date']][] = $item;
}
$res = $a;
unset($res['items']);
$res['items'] = array_values($new);


var_dump($res);

输出:

array(2) {
  ["category"]=>
  string(5) "Music"
  ["items"]=>
  array(3) {
    [0]=>
    array(3) {
      ["date"]=>
      string(10) "2018-11-28"
      [0]=>
      array(3) {
        ["ID"]=>
        string(1) "1"
        ["start_date"]=>
        string(10) "2018-11-20"
        ["end_date"]=>
        string(10) "2018-11-28"
      }
      [1]=>
      array(3) {
        ["ID"]=>
        string(1) "2"
        ["start_date"]=>
        string(10) "2018-11-22"
        ["end_date"]=>
        string(10) "2018-11-28"
      }
    }
    [1]=>
    array(2) {
      ["date"]=>
      string(10) "2018-11-30"
      [0]=>
      array(3) {
        ["ID"]=>
        string(1) "3"
        ["start_date"]=>
        string(10) "2018-11-26"
        ["end_date"]=>
        string(10) "2018-11-30"
      }
    }
    [2]=>
    array(3) {
      ["date"]=>
      string(10) "2018-11-31"
      [0]=>
      array(3) {
        ["ID"]=>
        string(1) "4"
        ["start_date"]=>
        string(10) "2018-11-27"
        ["end_date"]=>
        string(10) "2018-11-31"
      }
      [1]=>
      array(3) {
        ["ID"]=>
        string(1) "4"
        ["start_date"]=>
        string(10) "2018-11-29"
        ["end_date"]=>
        string(10) "2018-11-31"
      }
    }
  }
}

https://3v4l.org/foKL7

答案 1 :(得分:0)

您可以使用函数式编程对 items 子数组进行分组和重新索引,而无需在全局空间中声明任何临时变量。

当您迭代 $array['items'] 的每一行时,使用临时键进行分组并将行推送到各自的组中。完成分组后,使用 array_values() 重新索引数据。

代码:(Demo)

$array = [
    "category" => "Music", 
    "items" => [
        ["ID" => "1", "start_date" => "2018-11-20", "end_date" => "2018-11-28"],
        ["ID" => "2", "start_date" => "2018-11-22", "end_date" => "2018-11-28"],
        ["ID" => "3", "start_date" => "2018-11-26", "end_date" => "2018-11-30"],
        ["ID" => "4", "start_date" => "2018-11-27", "end_date" => "2018-11-31"],
        ["ID" => "4", "start_date" => "2018-11-29", "end_date" => "2018-11-31"]
    ]
];

$array["items"] = array_values(
    array_reduce(
        $array["items"],
        function ($carry, $row) {
            $carry[$row["end_date"]]["data"] = $row["end_date"];
            $carry[$row["end_date"]][] = $row;
            return $carry;
        }
    )
);
var_export($array);