合并两个通过共享列值相关的二维数组中的行

问题描述 投票:0回答:5

我有两个数组。我想将它们合并到相同的键和值上。如果它们具有相同的

ur_user_id
,那么它们将被合并。
array2
只为
array1
提供一些额外的数据,所以
new_array.length
=
array1.length
array1
只是从
array2
获取附加数据。

$array1 =    
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC'),
    );
$array2 = 
    array(
        array('ur_user_id' => 5,'ur_code' => 'EE','ur_user_role' => 'testE'),
        array('ur_user_id' => 4,'ur_code' => 'DD','ur_user_role' => 'testD'),
        array('ur_user_id' => 6,'ur_code' => 'FF','ur_user_role' => 'testF'),
        array('ur_user_id' => 3,'ur_code' => 'CC','ur_user_role' => 'testC'),
        array('ur_user_id' => 1,'ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id' => 2,'ur_code' => 'BB','ur_user_role' => 'testB'),
    );    

那么新数组必须如下所示。它将具有

array1
array2
的值。

$new_array =    
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA','ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB','ur_code' => 'BB','ur_user_role' => 'testB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC','ur_code' => 'CC','ur_user_role' => 'testC'),
    );

array1.length
始终小于或等于
array2.length
,且绝不会大于。并且两个数组的顺序并不总是有序的。我已经尝试过下面的函数,但它对我不起作用,而且我不太擅长循环。

function merge_common_keys(){
    $arr = func_get_args();
    $num = func_num_args();

    $keys = array();
    $i = 0;
    for ($i=0; $i<$num; ++$i){
        $keys = array_merge($keys, array_keys($arr[$i]));
    }
    $keys = array_unique($keys);

    $merged = array();

    foreach ($keys as $key){
        $merged[$key] = array();
        for($i=0; $i<$num; ++$i){
            $merged[$key][] = isset($arr[$i][$key]) ? $arr[$i][$key] : null;
        }
    }
    return $merged;
}

根据给定的数组,结果是这样的。它只在同一个键上合并。

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [ur_user_id] => 1
                    [ur_fname] => PerA
                    [ur_lname] => SonA
                )

            [1] => Array
                (
                    [ur_user_id] => 5
                    [ur_code] => AA-BB-CC
                    [ur_user_role] => testE
                )

        )
php arrays multidimensional-array grouping merging-data
5个回答
2
投票

当您需要迭代检查/搜索值(实际上是唯一标识符)时,最佳性能方法通常是:

  1. 生成一个键控数组并
  2. 迭代调用
    isset()
    (而不是
    in_array()
    array_search()

ur_user_id
是您的“唯一标识符”。
$array2
是通过使用
ur_user_id
array_column()
值指定为键来准备的。
$array1
控制迭代次数。
我的方法将检查
$array1
$array2
之间的对应行(以避免 Notices),然后使用联合运算符 (
+=
) 将
$array2
数据附加到
$array1
的每个原始行。
foreach 循环中的
&
“通过引用修改”——这表示正在“处理”实际输入数组,而不是输入数组的副本

代码:(演示

$array1 =    
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC'),
    );
$array2 = 
    array(
        array('ur_user_id' => 5,'ur_code' => 'EE','ur_user_role' => 'testE'),
        array('ur_user_id' => 4,'ur_code' => 'DD','ur_user_role' => 'testD'),
        array('ur_user_id' => 6,'ur_code' => 'FF','ur_user_role' => 'testF'),
        array('ur_user_id' => 3,'ur_code' => 'CC','ur_user_role' => 'testC'),
        array('ur_user_id' => 1,'ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id' => 2,'ur_code' => 'BB','ur_user_role' => 'testB'),
    );  

$keyed = array_column($array2, NULL, 'ur_user_id'); // replace indexes with ur_user_id values

foreach ($array1 as &$row) {       // write directly to $array1 while iterating
    if (isset($keyed[$row['ur_user_id']])) { // check if shared key exists
        $row += $keyed[$row['ur_user_id']]; // append associative elements
    }
}

var_export($array1);

输出:

array (
  0 => 
  array (
    'ur_user_id' => 1,
    'ur_fname' => 'PerA',
    'ur_lname' => 'SonA',
    'ur_code' => 'AA',
    'ur_user_role' => 'testA',
  ),
  1 => 
  array (
    'ur_user_id' => 2,
    'ur_fname' => 'PerB',
    'ur_lname' => 'SonB',
    'ur_code' => 'BB',
    'ur_user_role' => 'testB',
  ),
  2 => 
  array (
    'ur_user_id' => 3,
    'ur_fname' => 'PerC',
    'ur_lname' => 'SonC',
    'ur_code' => 'CC',
    'ur_user_role' => 'testC',
  ),
)

1
投票

尝试一下这段代码,它可能对你有帮助,它很短并且没有遍历循环:

    usort($array2,function($a,$b){
        return strnatcmp($a['ur_user_id'],$b['ur_user_id']);
    });
    $array3 = array_replace_recursive($array1, $array2);

    $result = array_uintersect($array3,$array1,function($a,$b){
        return strnatcmp($a['ur_user_id'],$b['ur_user_id']);
    });
    print_r($result);

输出

Array
(
    [0] => Array
        (
            [ur_user_id] => 1
            [ur_fname] => PerA
            [ur_lname] => SonA
            [ur_code] => AA
            [ur_user_role] => testA
        )

    [1] => Array
        (
            [ur_user_id] => 2
            [ur_fname] => PerB
            [ur_lname] => SonB
            [ur_code] => BB
            [ur_user_role] => testB
        )

    [2] => Array
        (
            [ur_user_id] => 3
            [ur_fname] => PerC
            [ur_lname] => SonC
            [ur_code] => CC
            [ur_user_role] => testC
        )

)

这是演示


1
投票

试试这个:

<?php

$array1 =    
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC'),
    );
$array2 = 
    array(
        array('ur_user_id' => 5,'ur_code' => 'EE','ur_user_role' => 'testE'),
        array('ur_user_id' => 4,'ur_code' => 'DD','ur_user_role' => 'testD'),
        array('ur_user_id' => 6,'ur_code' => 'FF','ur_user_role' => 'testF'),
        array('ur_user_id' => 3,'ur_code' => 'CC','ur_user_role' => 'testC'),
        array('ur_user_id' => 1,'ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id' => 2,'ur_code' => 'BB','ur_user_role' => 'testB'),
    );


$result = array();

$userIdsFromArray1 = array_column($array1, 'ur_user_id');


foreach($array2 as $subarray)
{
    if(in_array($subarray['ur_user_id'], $userIdsFromArray1))
    {
        $result[] = array_merge($subarray, getDataFromArray1ByUserId($array1, $subarray['ur_user_id']));
    }
}


function getDataFromArray1ByUserId($array1, $userId)
{
    foreach($array1 as $key => $data)
    {
        if($data['ur_user_id'] == $userId)
            return $data;
    }

    return array();
}

 usort($result,function($a,$b){
    return strnatcmp($a['ur_user_id'],$b['ur_user_id']);
});

print_r($result);

工作示例:点击!


1
投票

在 foreach 循环中尝试这三行代码,如下所示:

$array1 =    
    array(
        array('ur_user_id'=> 1,'ur_fname'=>'PerA','ur_lname'=>'SonA'),
        array('ur_user_id'=> 2,'ur_fname'=>'PerB','ur_lname'=>'SonB'),
        array('ur_user_id'=> 3,'ur_fname'=>'PerC','ur_lname'=>'SonC'),
    );
$array2 = 
    array(
        array('ur_user_id' => 5,'ur_code' => 'EE','ur_user_role' => 'testE'),
        array('ur_user_id' => 4,'ur_code' => 'DD','ur_user_role' => 'testD'),
        array('ur_user_id' => 6,'ur_code' => 'FF','ur_user_role' => 'testF'),
        array('ur_user_id' => 3,'ur_code' => 'CC','ur_user_role' => 'testC'),
        array('ur_user_id' => 1,'ur_code' => 'AA','ur_user_role' => 'testA'),
        array('ur_user_id' => 2,'ur_code' => 'BB','ur_user_role' => 'testB'),
    );

$newArray =array(); 

foreach($array1 as $key => $val)
{
    $ids = array_map(function ($ar) {return $ar['ur_user_id'];}, $array2); //get the all the user ids from array 2
    $k = array_search($val['ur_user_id'],$ids); // find the key of user id in ids array
    $newArray[] = array_merge($array1[$key],$array2[$k]); /// merge the first array key with second
}   

echo "<pre>"; print_r($newArray);

这会给你:

(
    [0] => Array
        (
            [ur_user_id] => 1
            [ur_fname] => PerA
            [ur_lname] => SonA
            [ur_code] => AA
            [ur_user_role] => testA
        )

    [1] => Array
        (
            [ur_user_id] => 2
            [ur_fname] => PerB
            [ur_lname] => SonB
            [ur_code] => BB
            [ur_user_role] => testB
        )

    [2] => Array
        (
            [ur_user_id] => 3
            [ur_fname] => PerC
            [ur_lname] => SonC
            [ur_code] => CC
            [ur_user_role] => testC
        )

)

现场演示


-1
投票

你最好这样做:

工作示例

$ids = array();
$out = array();
foreach($array1 as $key => $value){
    if(isset($array2[$key]))
        $out[$key][] = $array2[$key];
    $out[$key][] = $value;
    $ids[] = $array2[$key]['ur_user_id'];
}

foreach($array2 as $key => $val){
    if(!in_array($val['ur_user_id'], $ids))
        $out[$key][] = $array2[$key];
}
© www.soinside.com 2019 - 2024. All rights reserved.