基于深度值如何合并数组?

3
Array (
    [0] => Array (
        [OrderProduct] => Array (
            [pro_code] => B1
            [totalQTY] => 4
        )
    )
    [1] => Array (
        [OrderProduct] => Array (
            [pro_code] => B2
            [totalQTY] => 4
        )
    )
    [2] => Array (
        [OrderProduct] => Array (
            [pro_code] => B4
            [totalQTY] => 4
        )
    )
)

Array (
    [0] => Array (
        [OrderProduct] => Array (
            [pro_code] => B1
            [totalDistSalesQTY] => 360
        )
    )
    [1] => Array (
        [OrderProduct] => Array (
            [pro_code] => B2
            [totalDistSalesQTY] => 600
        )
    )
    [2] => Array (
        [OrderProduct] => Array (
            [pro_code] => B3
            [totalDistSalesQTY] => 600
        )
    )
)   

我希望能够根据上述两个数组中的pro_code值进行合并。以下是预期结果:
Array (
    [0] => Array (
        [OrderProduct] => Array (
            [pro_code] => B1
            [totalDistSalesQTY] => 360
            [totalQTY] => 4
        )
    )
    [1] => Array (
        [OrderProduct] => Array (
            [pro_code] => B2
            [totalDistSalesQTY] => 600
            [totalQTY] => 4
        )
    )
    [2] => Array (
        [OrderProduct] => Array (
            [pro_code] => B3
            [totalDistSalesQTY] => 600
        )
    )
    [3] => Array (
        [OrderProduct] => Array (
            [pro_code] => B4
            [totalQTY] => 4
        )
    )
)

我想合并多个数组,请帮助我正确地合并它们。我尝试了许多技巧来合并它们,但仍然无法找到解决方法。请帮我解决这个问题。


3
你尝试了什么? - M A SIDDIQUI
最后,你真正想要什么? - Gabriel Heming
你尝试过使用array_diff()函数吗? => http://php.net/manual/zh/function.array-diff.php - Bast
3个回答

1
所以基本上,你需要做的是在序列上实现一个合并算法。这是基本的编程论文之一,所以不应该太难。
首先,您需要按唯一、严格可排序的值(这是这里的pro_code)升序排序序列(示例中的数组)。
其次,您需要同时遍历两个序列。如果当前项的唯一键(pro_code)匹配,则将它们合并并推送到结果数组中;如果不匹配,则将具有较小键的项推送到结果数组中。推送后,增加已推送序列的索引。
在达到其中一个序列的末尾后,将剩余部分推送到结果数组中。
以下是php实现的样子:
<?php

//  Compare func for usort
function compare($a, $b) {
    return strcmp($a['OrderProduct']['pro_code'], $b['OrderProduct']['pro_code']);

}

//  Sort array with usort
function sort_array(&$a) {
    usort($a, 'compare');

}

//  Print array
function print_a(&$a) {
    print '<pre>';
    print_r($a);
    print '</pre>';

}

function list_merge(&$a,  &$b) {
    $resp = array();

    $ia = 0;
    $ib = 0;
    while($ia < count($a) || $ib < count($b)) {
        //  Check if any of the arrays reached its end
        //  If not, check for merge
        if(isset($a[$ia]) && isset($b[$ib])) {
            //  Product codes are matching, 
            //  Push merged to $resp
            if(strcmp($a[$ia]['OrderProduct']['pro_code'], $b[$ib]['OrderProduct']['pro_code']) == 0) {
                $resp[] = array(
                    'OrderProduct'  => array(
                            'pro_code'  => $a[$ia]['OrderProduct']['pro_code'],
                            'totalQTY'  => $a[$ia]['OrderProduct']['totalQTY'] + $b[$ib]['OrderProduct']['totalQTY'],
                    ),
                );

                //  If merge increment both
                $ia++;
                $ib++;

            }
            //  Product code of element of $a is lesser,
            //  Push $a to $resp
            elseif(strcmp($a[$ia]['OrderProduct']['pro_code'], $b[$ib]['OrderProduct']['pro_code']) < 0) {
                $resp[] = array(
                    'OrderProduct'  => array(
                            'pro_code'  => $a[$ia]['OrderProduct']['pro_code'],
                            'totalQTY'  => $a[$ia]['OrderProduct']['totalQTY'],
                    ),
                );

                //  Increment only pushed
                $ia++;

            }
            //  Product code of element of $b is lesser,
            //  Push $b to $resp
            else {
                $resp[] = array(
                    'OrderProduct'  => array(
                            'pro_code'  => $b[$ib]['OrderProduct']['pro_code'],
                            'totalQTY'  => $b[$ib]['OrderProduct']['totalQTY'],
                    ),
                );

                //  Increment only pushed
                $ib++;

            }

        }
        //  Else automatically push the existing array
        //  If $a exists
        elseif(isset($a[$ia])) {
            $resp[] = array(
                'OrderProduct'  => array(
                        'pro_code'  => $a[$ia]['OrderProduct']['pro_code'],
                        'totalQTY'  => $a[$ia]['OrderProduct']['totalQTY'],
                ),
            );

            //  Increment only pushed
            $ia++;

        }
        //  Else automatically push the existing array
        //  If $b exists
        else {
            $resp[] = array(
                'OrderProduct'  => array(
                        'pro_code'  => $b[$ib]['OrderProduct']['pro_code'],
                        'totalQTY'  => $b[$ib]['OrderProduct']['totalQTY'],
                ),
            );

            //  Increment only pushed
            $ib++;

        }

    }

    return $resp;

}


//  Data structures
$array1 = array(
    array(
        'OrderProduct'  => array(
                'pro_code'  => 'B1',
                'totalQTY'  => 4,
        ),
    ),
    array(
        'OrderProduct'  => array(
                'pro_code'  => 'B2',
                'totalQTY'  => 4,
        ),
    ),
    array(
        'OrderProduct'  => array(
                'pro_code'  => 'B4',
                'totalQTY'  => 4,
        ),
    ),
);

$array2 = array(
    array(
        'OrderProduct'  => array(
                'pro_code'  => 'B1',
                'totalQTY'  => 360,
        ),
    ),
    array(
        'OrderProduct'  => array(
                'pro_code'  => 'B2',
                'totalQTY'  => 600,
        ),
    ),
    array(
        'OrderProduct'  => array(
                'pro_code'  => 'B3',
                'totalQTY'  => 600,
        ),
    ),
);


//  Sort arrays by product code
sort_array($array1);
sort_array($array2);

//  Merge arrays with list merge
$array3 = list_merge($array1, $array2);

//  Print arrays for check
print_a($array1);
print_a($array2);
print_a($array3);

我希望我能提供一些帮助。


1

这是我能够精简的方法。它实际上只有三个简单的步骤和一个自定义函数。

代码:

$QTY=[
    ["OrderProduct"=>
        ["pro_code"=>"B1","totalQTY"=>"4"]],
    ["OrderProduct"=>
        ["pro_code"=>"B2","totalQTY"=>"4"]],
    ["OrderProduct"=>
        ["pro_code"=>"B4","totalQTY"=>"4"]]
];
$DSQTY=[
    ["OrderProduct" =>
        ["pro_code"=>"B1","totalDistSalesQTY"=>"360"]],
    ["OrderProduct"=>
        ["pro_code"=>"B2","totalDistSalesQTY"=>"600"]],
    ["OrderProduct"=>
        ["pro_code"=>"B3","totalDistSalesQTY"=>"600"]]
];

function getDeepColumn($a,$c,$result=[]){
    foreach(array_column(array_column($a,"OrderProduct"),$c,'pro_code') as $k=>$v){
        $result[$k][$c]=$v;
    }
    return $result;
}

$merged=array_merge_recursive(getDeepColumn($QTY,'totalQTY'),getDeepColumn($DSQTY,'totalDistSalesQTY'));
ksort($merged);  // make sure B4 is not before B3
foreach($merged as $k=>$a){
    $result[]=["OrderProduct"=>array_merge(["pro_code"=>$k],$a)];
}
var_export($result);

自定义函数解释: getDeepColumn() 使用 array_column() 与指定的数组和指定的列名提取所有 OrderProduct 子数组中所需的值。 列值暂时存储在一个名为 $result 的数组中。 $result 的一级键是未来合并用途的 pro_code 值。$result 的子数组由指定列的名称(作为键)和指定列的值(作为值)组成。
首先,使用 array_merge_recursive() 混合所需的深层列值。
接下来,$merge 使用唯一的 pro_code 键进行 ksort() 排序。
最后,使用foreach()重新索引所有OrderProduct子数组,并将pro_code值返回到其在OrderProduct子数组中的正确位置。
输出:
array (
  0 => 
  array (
    'OrderProduct' => 
    array (
      'pro_code' => 'B1',
      'totalQTY' => '4',
      'totalDistSalesQTY' => '360',
    ),
  ),
  1 => 
  array (
    'OrderProduct' => 
    array (
      'pro_code' => 'B2',
      'totalQTY' => '4',
      'totalDistSalesQTY' => '600',
    ),
  ),
  2 => 
  array (
    'OrderProduct' => 
    array (
      'pro_code' => 'B3',
      'totalDistSalesQTY' => '600',
    ),
  ),
  3 => 
  array (
    'OrderProduct' => 
    array (
      'pro_code' => 'B4',
      'totalQTY' => '4',
    ),
  ),
)

0
如果你在结果数组中使用产品代码作为键,这将非常简单。
// combine the two arrays together and iterate all their rows
foreach (array_merge($array1, $array2) as $row) {

    // get the code
    $code = $row['OrderProduct']['pro_code'];

    // get the previous value for that code, or an empty array if there isnt' one
    $prev = $result[$code]['OrderProduct'] ?? [];

    // merge the previous value with the new value
    $result[$code]['OrderProduct'] = array_merge($prev, $row['OrderProduct']);
}

你最终会在结果数组中得到产品代码键,这可能是可以接受的。如果不可以接受,你可以使用$result = array_values($result)将它们移除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接