将第一个数组中特定的键和值合并到第二个数组中。

3

我有两个数组

$arr1 = Array ( 
    [0] => Array ( [customer_id] => 1 [Expire] => 2019-05-14 [paid] => 1 ) 
    [1] => Array ( [customer_id] => 2 [Expire] => 2019-06-20 [paid] => 0 ))

并且。
$arr2 = Array ( 
    [0] => Array ( [id] => 3943 [customer_id] => 1 [Expire] => 2019-05-14 ) 
    [1] => Array ( [id] => 3944 [customer_id] => 1[Expire] => 2019-05-14 ) 
    [2] => Array ( [id] => 4713 [customer_id] => 2 [Expire] => 2019-06-20 ) 
)

尝试将第一个数组的键和值[paid]=>1或0放入第二个数组中,如果客户ID和过期时间匹配。
Array ( 
    [0] => Array ( [id] => 3943 [customer_id] => 1 [Expire] => 2019-05-14 [paid] => 1) 
    [1] => Array ( [id] => 3944 [customer_id] => 1 [Expire] => 2019-05-14 [paid] => 1) 
    [2] => Array ( [id] => 4713 [customer_id] => 2 [Expire] => 2019-06-20 [paid] => 0) 
)

我尝试在php中合并数组,但没有得到我想要的结果。是否有任何php函数可以实现此功能?


1
编号为3945,客户编号为2的数据发生了什么?为什么它没有出现在最终期望的输出中? - Qirel
你能否将数组的索引设置为customer_id而不是0、1、2等吗?这样会使事情变得更容易。 - Ali Elkhateeb
客户编号值不能为0。 - Deepak3301086
最好向我们展示你尝试过什么,并说明哪里出了问题。@Qirel 违规的 ID 已于五分钟前被 Deepak3301086 移除。 - KIKO Software
4个回答

3
循环遍历你的第二个数组$arr2,并查找第一个数组$arr1中与当前迭代$arr2相同的customer_id列所在的索引。使用array_search()返回该索引,然后我们可以使用它来获取该数组的paid索引。然后我们通过执行$a['paid'] = $paid;将其附加到我们的数组$arr2中。

由于我们通过引用循环数组(循环中$a之前的&),我们对它所做的更改将应用于原始数组。
foreach ($arr2 as &$a) {
    $customerID = $a['customer_id'];      // This customer ID
    $arr1_key = array_search($customerID, array_column($arr1, 'customer_id'));   // Find the index of this customerID in the first array
    $paid = $arr1[$arr1_key]['paid'];     // Find the paid value matching that customer ID
    $a['paid'] = $paid;
}

更新
如果需要匹配ID和过期日期,那么可以使用array_filter()$arr1中获取与日期和ID匹配的数组元素。然后使用reset()来获取该数组中的第一个元素。

foreach ($arr2 as &$a) {
    // Find the sub-array of $arr1 that matches this array's date and ID
    $arr1_match  = array_filter($arr1, function($v) use ($a) {
        return $v['customer_id'] == $a['customer_id'] && $v['Expire'] == $a['Expire'];
    });
    // Get the first element from the result
    $paid = reset($arr1_match)['paid'];
    // Append the paid-value to this array (done by reference)
    $a['paid'] = $paid;
}

这当然是一个好的解决方案。只是想指出你也可以反过来做:foreach ($arr1 as 并在 $arr2 的一列中搜索。为什么?因为 $arr1 似乎是传入的付款信息,而 $arr2 是现有客户列表。我还会把 array_column($arr1, 'customer_id') 放在 foreach 循环外面。但是,这些都是小细节,这绝对是最好的解决方案。你得到了我的赞同。 - KIKO Software
嗯,那很可能是这样。问题在于第二个数组中有多个相同的客户ID实例,但第一个数组中只有一个。而且第一个数组中的条目比第二个数组少。这意味着要获得所需的结果会更加棘手(也就是说,你不能仅仅用上面的代码片段替换$arr1$arr2或反之亦然)。不过你关于数组定义的想法可能是正确的。 - Qirel
只有在客户ID匹配的情况下才能工作,如果日期不同,则无法工作。请查看https://3v4l.org/TeTpK。 - Deepak3301086
需要找到(customer_id和Expire)的索引。然后匹配两个索引,如果匹配,则将paid值放入其中。 - Deepak3301086
使用 array_filter() 函数来获取 $arr1 中正确的子数组,参见修订后的答案。 - Qirel
显示剩余2条评论

1
有时候事情可能会以困难的方式完成 :)
<?php
$arr1 = [
    ['customer_id' => 1, 'Expire' => '2019-05-14', 'paid' => 1],
    ['customer_id' => 2, 'Expire' => '2019-06-20', 'paid' => 0],
];

$arr2 = [
    ['id' => 3943, 'customer_id' => 1, 'Expire' => '2019-05-14'],
    ['id' => 3944, 'customer_id' => 1, 'Expire' => '2019-05-14'],
    ['id' => 3945, 'customer_id' => 2, 'Expire' => '2019-05-14'],
    ['id' => 4713, 'customer_id' => 2, 'Expire' => '2019-06-20'],
];

foreach ($arr2 as &$item2) {
    foreach ($arr1 as $item1) {
        if (
            $item2['customer_id'] === $item1['customer_id']
            && $item2['Expire'] === $item1['Expire']
        ) {
            $item2['paid'] = $item1['paid'];
            break;
        }
    }
}
unset($item2);

var_dump($arr2);

我认为在这里使用 'Identical Operator'(三个等号)有点过头了,'Equal Operator'(两个等号)就可以了。如果一个'id'是3943(整数)或者"3943"(字符串),我并不在意,而且我认为它们应该被视为相等的。 - KIKO Software

1
这可以解决问题:

$arr1 = array(

            ["customer_id"=>1,"Expire"=> "2019-05-14", "paid"=>1],
            ["customer_id"=>2,"Expire"=> "2019-06-20", "paid"=>0]
    );


$arr2 = array(
           ["id"=>3943, "customer_id"=>1,"Expire"=> "2019-05-14"],
           ["id"=>3944,"customer_id"=>2,"Expire"=> "2019-06-20"],
           ["id"=>4713,"customer_id"=>1,"Expire"=> "2019-05-14"]
    );    


$result= array();    

function getRowByCustomerID($id, $array){
    foreach($array as $value){
        if($value['customer_id'] ==$id){
            return $value;
        }
    }
    return null;
}    

foreach($arr2 as $subarr){

    $object = getRowByCustomerID($subarr['customer_id'],$arr1 );
    if(!is_null($object)){
        $object['id']=$subarr['id'];
        $result[]= $object;
    }
}    



var_dump($result);

输出结果与您所需的相似:
array(3) {
  [0]=>
  array(4) {
    ["customer_id"]=>
    int(1)
    ["Expire"]=>
    string(10) "2019-05-14"
    ["paid"]=>
    int(1)
    ["id"]=>
    int(3943)
  }
  [1]=>
  array(4) {
    ["customer_id"]=>
    int(2)
    ["Expire"]=>
    string(10) "2019-06-20"
    ["paid"]=>
    int(0)
    ["id"]=>
    int(3944)
  }
  [2]=>
  array(4) {
    ["customer_id"]=>
    int(1)
    ["Expire"]=>
    string(10) "2019-05-14"
    ["paid"]=>
    int(1)
    ["id"]=>
    int(4713)
  }
}

你的 $arr2 和问题中的不一样。请查看 'paid' 键。 - KIKO Software
你说得对,我刚刚更新了我的答案,这不会影响结果。谢谢@KIKOSoftware。 - Yassine CHABLI

1
如果您无法更改第一个数组的布局,我认为最好先创建一个中间数组,记录每个客户端的所有到期日期。
以下实现不需要使用嵌套循环。
<?php
$arr1 = [
    ['customer_id' => 1, 'Expire' => '2019-05-14', 'paid' => 1],
    ['customer_id' => 2, 'Expire' => '2019-06-20', 'paid' => 0],
];

$arr2 = [
    ['id' => 3943, 'customer_id' => 1, 'Expire' => '2019-05-14'],
    ['id' => 3944, 'customer_id' => 1, 'Expire' => '2019-05-14'],
    ['id' => 3945, 'customer_id' => 2, 'Expire' => '2019-05-14'],
    ['id' => 4713, 'customer_id' => 2, 'Expire' => '2019-06-20'],
];

// Create a list of all paid, expiry dates, keyed by customer_id
$payed = [];

foreach ($arr1 as $item) {
    if (!isset($payed[$item['customer_id']])) {
        $payed[$item['customer_id']] = [];
    }
    $payed[$item['customer_id']][] = $item['Expire'];
}

// Lookup the customer and expire date for every entry
$arr2 = array_map(function($item) use ($payed) { 
    $item['paid'] = in_array($item['Expire'], $payed[$item['customer_id']] ?? []);
    return $item;
}, $arr2);

结果:

Array
(
[0] => Array
    (
        [id] => 3943
        [customer_id] => 1
        [Expire] => 2019-05-14
        [paid] => 1
    )

[1] => Array
    (
        [id] => 3944
        [customer_id] => 1
        [Expire] => 2019-05-14
        [paid] => 1
    )

[2] => Array
    (
        [id] => 3945
        [customer_id] => 2
        [Expire] => 2019-05-14
        [paid] => 
    )

[3] => Array
    (
        [id] => 4713
        [customer_id] => 2
        [Expire] => 2019-06-20
        [paid] => 1
    )

)

查看演示


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