简体   繁体   English

如何比较和以后合并两个多维数组

[英]How to compare and later merge two multidimensional arrays

I am trying to merge two multidimensional arrays in following way (example arrays are only examples, real ones are very long and have thousands of items): 我正在尝试以以下方式合并两个多维数组(示例数组仅是示例,真正的数组很长,并且有成千上万个项目):

$array_a: $ array_a:

[0] => Array
    (
        [date] => 2018-02-25 15:12
        [request] => 0
    )
[1] => Array
    (
        [date] => 2018-02-25 15:13
        [request] => 0
    )
[2] => Array
    (
        [date] => 2018-02-25 15:14
        [request] => 0
    )
[3] => Array
    (
        [date] => 2018-02-25 15:15
        [request] => 0
    )

$array_b: $ array_b:

[0] => Array
    (
        [date] => 2018-02-25 15:12
        [request] => 11
    )
[1] => Array
    (
        [date] => 2018-02-25 15:13
        [request] => 5
    )
[2] => Array
    (
        [date] => 2018-02-25 15:15
        [request] => 2
    )

Needed result: 所需结果:

[0] => Array
    (
        [date] => 2018-02-25 15:12
        [request] => 11
    )
[1] => Array
    (
        [date] => 2018-02-25 15:13
        [request] => 5
    )
[2] => Array
    (
        [date] => 2018-02-25 15:14
        [request] => 0
    )
[3] => Array
    (
        [date] => 2018-02-25 15:15
        [request] => 2
    )

Any? 任何? Thanks. 谢谢。

One way to go: 一种方法:

foreach($a as $v) {
        $res[$v['date']] = $v['request'];
}

foreach($b as $v) {
        if(isset($res[$v['date']])) {
                if($v['request'] > $res[$v['date']])
                        $res[$v['date']] = $v['request'];
        } else {
                $res[$v['date']] == $v['request'];
        }
}

foreach($res as $k=>$v)
        $out[] = array("date" => $k, "request" => $v);

where $a and $b are your arrays and $out is the final result. 其中$a$b是您的数组,而$out是最终结果。

How it works: 这个怎么运作:

Since we are comparing the dates and we know they are unique, we put them into a temporary array(in my case $res ) as keys of the elements(keys of arrays are unique). 由于我们正在比较日期,并且知道它们是唯一的,因此我们将它们放入一个临时数组(在我的情况下$res )作为元素的键(数组的键是唯一的)。 For values of each element we compare the values of requests and store the bigger one. 对于每个元素的值,我们比较请求的值并存储更大的请求。

So, the first foreach loop loops over the first array and adds elemenets to $res in the form of: 因此,第一个foreach循环遍历第一个数组,并以以下形式将元素添加到$res中:

$res['2018-02-25 15:12'] = 0;

The second foreach loop loops over all elements of the second array, however, in here we also want to make sure we are using the bigger value for requests. 第二个foreach循环foreach第二个数组的所有元素,但是,在这里,我们还要确保对请求使用更大的值。

So this is, the if logic checks if the element exists, and if it does - gets the bigger value for requests and stores it to the date. 因此, if逻辑检查元素是否存在,如果存在,则为请求获取更大的值并将其存储到日期。 If not - it does exactly what it did in the first foreach loop(creates new element). 如果不是,它将完全执行第一个foreach循环中的操作(创建新元素)。

Lastly, we want to put the array together to how it looked like, so we loop over $res and re-create the array as the original two looked like. 最后,我们希望将数组放到看起来像的样子,因此我们遍历$res并重新创建数组,就像原来的两个一样。 The resulting $out holds what you requested. 结果$out保留了您所请求的内容。

I can give you the result, however I don't know the logic that goes in the callback body. 我可以给你结果,但是我不知道回调主体中的逻辑。

$array_c = array_values(array_reduce(array_merge($a, $b), function($carry, $item) {
    $carry[$item['date']] = $item;
    return $carry;
}, []));

https://3v4l.org/fSVoj https://3v4l.org/fSVoj

What I'm doing is combining the arrays (they're all subset'd, so no inherent conflicts), then I go through and "reduce down" to an array key > value pairing, the key being the date/time, the value being the set. 我正在做的是组合数组(它们都是子集,因此没有固有的冲突),然后遍历并“简化”为数组键>值配对,键是日期/时间,值是集合。 This gives the effect of coalescing each date/time to the same key in that array. 这样可以产生将每个日期/时间合并到该数组中相同键的效果。 The callback in this case simply "remembers" the last date/time block encountered, hence the "not sure what's needed" question. 在这种情况下,回调仅“记住”遇到的最后一个日期/时间块,因此出现“不确定需要什么”的问题。

Lastly, I get a version of the array with the date/times replaced with indexes ( array_values() ). 最后,我得到了数组的版本,其中日期/时间被索引( array_values() )取代。 This is also interesting, because sorting by date would be fairly easy if the array_values() call were moved to later. 这也很有趣,因为如果将array_values()调用移到后面, array_values()日期排序将相当容易。

This gives: 这给出:

array(4) {
  [0]=>
  array(2) {
    ["date"]=>
    string(16) "2018-02-25 15:12"
    ["request"]=>
    int(11)
  }
  [1]=>
  array(2) {
    ["date"]=>
    string(16) "2018-02-25 15:13"
    ["request"]=>
    int(5)
  }
  [2]=>
  array(2) {
    ["date"]=>
    string(16) "2018-02-25 15:14"
    ["request"]=>
    int(0)
  }
  [3]=>
  array(2) {
    ["date"]=>
    string(16) "2018-02-25 15:15"
    ["request"]=>
    int(2)
  }
}

Different things can be done, like only keep the first, or add each request (they're all zero in the first array). 可以完成不同的操作,例如仅保留第一个请求,或添加每个请求(第一个数组中的请求都为零)。 The mechanism should be the same though. 虽然机制应该相同。

If you have to add values, you could use something like this : 如果您必须添加值,则可以使用如下所示的内容:

$out = [];
// create new array using date as key, "object" as value.
foreach ($arr1 as $itm) {
    $out[$itm['date']] = $itm;
}
// foreach each element of the second array,
foreach ($arr2 as $itm) {
    // if it doesn't exists in the out array, simply add it
    if (!isset($out[$itm['date']])) $out[$itm['date']] = $itm ;
    // otherwise, add request to the first
    else $out[$itm['date']]['request'] += $itm['request'];
}
ksort($out); // Sort by date (Optional)
$out = array_values($out); // get values to remove dates from keys
print_r($out);

Outputs : 输出:

Array
(
    [0] => Array
        (
            [date] => 2018-02-25 15:12
            [request] => 11
        )

    [1] => Array
        (
            [date] => 2018-02-25 15:13
            [request] => 5
        )

    [2] => Array
        (
            [date] => 2018-02-25 15:14
            [request] => 0
        )

    [3] => Array
        (
            [date] => 2018-02-25 15:15
            [request] => 2
        )

)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM