Php数组按日期分组

时间:2017-08-23 08:08:42

标签: php arrays

我在下面的PHP代码中有一个数组,我想将此数组转换为按数据值分组。它总是很难简化数组。

原始阵列:

  Array
  (
    [0] => Array
        (
            [date] => 2017-08-22
            [AAA] => 1231
        )
    [1] => Array
        (
            [date] => 2017-08-21
            [AAA] => 1172
        )
    [2] => Array
        (
            [date] => 2017-08-20
            [AAA] => 1125
        )
    [3] => Array
        (
            [date] => 2017-08-21
            [BBB] => 251
        )
    [4] => Array
        (
            [date] => 2017-08-20
            [BBB] => 21773
        )
    [5] => Array
        (
            [date] => 2017-08-22
            [CCC] => 3750
        ) 
    [6] => Array
        (
            [date] => 2017-08-20
            [CCC] => 321750
        )
  )

以下是我想要的数组:

  Array
  (
    [2017-08-22] => Array
        (
            [AAA] => 1231 
            [CCC] => 3750
        )
    [2017-08-21] => Array
        (
            [AAA] => 1172
            [BBB] => 251
        )
    [2017-08-20] => Array
        (
            [AAA] => 1125
            [BBB] => 21773
            [CCC] => 321750
        )
  )

如果数据不存在,也可以使用空的空值。 [BBB] => 2017-08-22为NULL。 有人可以帮忙吗?提前谢谢......

6 个答案:

答案 0 :(得分:2)

一个简单的循环应该这样做..

{{1}}

答案 1 :(得分:1)

这里:这应该做的工作。

$dst_array = array();
foreach ($array as $outerval) {
    foreach ($outerval as $key => $innerval) {
        if ($key != 'date') {
            $dst_array[$outerval['date']][$key] = $innerval;
        }
    }
}

它遍历数组,然后遍历每个子数组中的条目。任何不是日期的任何日期都在子数组中的目标数组中分配,该数组与其日期和当前密钥相对应。

答案 2 :(得分:0)

我相信这个解决方案对您有用:

<?php
$array = Array
(
    0 => Array
    (
        'date' => '2017-08-22',
        'AAA' => '1231',
    ),
    1 => Array
    (
        'date' => '2017-08-21',
        'AAA' => '1172',
    ),
    2 => Array
    (
        'date' => '2017-08-20',
        'AAA' => '1125'
    ),
    3 => Array
    (
        'date' => '2017-08-21',
        'BBB' => '251'
    ),
    4 => Array
    (
        'date' => '2017-08-20',
        'BBB' => '21773',
    ),
    5 => Array
    (
        'date' => '2017-08-22',
        'CCC' => '3750'
    ),
    6 => Array
    (
        'date' => '2017-08-20',
        'CCC' => '321750'
    )
);
echo '<pre>';
$array1 = array('AAA' => null, 'BBB' => null, 'CCC' => null);
$array2 = array();

array_walk($array, function ($v) use (&$array2, $array1) {
    $a = $v['date'];
    if (!isset($array2[$a])) {
        $array2[$a] = $array1;
    }
    unset($v['date']);
    $array2[$a] = array_merge($array2[$a], $v);
});

print_r($array2);

<强>输出

Array
(
    [2017-08-22] => Array
        (
            [AAA] => 1231
            [BBB] => 
            [CCC] => 3750
        )

    [2017-08-21] => Array
        (
            [AAA] => 1172
            [BBB] => 251
            [CCC] => 
        )

    [2017-08-20] => Array
        (
            [AAA] => 1125
            [BBB] => 21773
            [CCC] => 321750
        )

)

检查输出:https://3v4l.org/NvLB8

答案 3 :(得分:0)

使用数组内部指针的另一种方法(快速和肮脏):

$newArray = [];
foreach ($array as $childArray) {
    $date = current($childArray);

    $value = next($childArray);  // this advances the internal pointer..
    $key = key($childArray);     // ..so that you get the correct key here

    $newArray[$date][$key] = $value;
}

这当然只适用于给定的数组结构。

答案 4 :(得分:0)

PHP函数array_reduce()的另一个完美用法示例:

// The input array
$input = array(
    0 => array(
        'date' => '2017-08-22',
        'AAA'  => '1231',
    ),
    // The rest of your array here...
);


$output = array_reduce(
    $input,
    function (array $carry, array $item) {
        // Extract the date into a local variable for readability and speed
        // It is used several times below
        $date = $item['date'];
        // Initialize the group for this date if it doesn't exist
        if (! array_key_exists($date, $carry)) {
            $carry[$date] = array();
        }

        // Remove the date from the item...
        // ...and merge the rest into the group of this date
        unset($item['date']);
        $carry[$date] = array_merge($carry[$date], $item);

        // Return the partial result
        return $carry;
    },
    array()
);

问题不明确。如果一个密钥(AAA f.e)出现在两个或多个日期,预期结果是什么?此答案仅保留与其关联的最后一个值。

答案 5 :(得分:0)

我绝对不建议任何涉及不止一个循环的技术-此过程当然可以在单个循环中执行。

如果您喜欢语言构造迭代,请使用foreach()循环:(Demo

$result = [];
foreach ($array as $row) {
    $date = $row['date'];
    unset($row['date']);
    $result[$date] = array_merge($result[$date] ?? [], $row);
}
var_export($result);

如果您希望使用函数式编程并且使用较少的全局变量,请使用array_reduce():(Demo

var_export(
    array_reduce(
        $array, 
        function($accumulator, $row) {
            $date = $row['date'];
            unset($row['date']);
            $accumulator[$date] = array_merge($accumulator[$date] ?? [], $row);
            return $accumulator;
        },
        []
    )
);

这些技术使用基于日期列值的键无条件地将数据推入子数组。

即使子数组元素的顺序更改,上述技术也将始终如一地工作。

??(空合并运算符)用于确保array_merge()始终在第一个参数中具有数组-如果处理给定日期的第一次出现,则只需合并当前迭代的数据(在unset()删除date元素之后,它剩下的内容)为空数组。