3

I have 2 array

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

and

$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 ) 
)

and try to put first array key and value [paid]=>1 or 0 in second array if customer id and expire match like

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) 
)

I try to merge array in php but not get exact what i want. Is there any php function to do it?.

4
  • 1
    What happened to the id 3945, customer_id 2? Why isn't that present in the final desired output? Commented Apr 9, 2019 at 8:35
  • Can you make the index of the array as the customer_id instead of 0,1,2..etc? It will make things much easier Commented Apr 9, 2019 at 8:37
  • customer_id value can't be 0 Commented Apr 9, 2019 at 8:40
  • It is best to show us what you've tried and say where it goes wrong. @Qirel The offending id was removed by Deepak3301086 five minutes ago. Commented Apr 9, 2019 at 8:43

4 Answers 4

3

Loop your second array $arr2, and find the index of the first array $arr1 where the column customer_id is the same as in the current iteration of $arr2. array_search() returns that index, which we can then use to fetch the paid index of that array. Then we append it to our array $arr2, by doing $a['paid'] = $paid;.

Since we loop the array by reference (the & before $a in the loop), the changes we make to it, will be applied back to the original array.

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;
}

Update
If you need it to match the ID as well as the expiration date, then use array_filter() to fetch the array-element within $arr1 that matches the date and the ID. Using reset(), we use the first element in that array.

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;
}
Sign up to request clarification or add additional context in comments.

7 Comments

This is, of course, a good solution. Just want to point out you could have done it the other way around: foreach ($arr1 as and search through a column of $arr2. Why? Because it seems that $arr1 is the incoming payment information and $arr2 is an existing list of customers. I also would put array_column($arr1, 'customer_id') outside the foreach loop. But hey, these are minor details, this is by far the best solution. You get my upvote.
Hmm, that may very well be. The issue is though that there are multiple instances of each customer ID in the second array, but only one in the first. There's also fewer entries in the first array than the second. Which means it'll be a tad more tricky to get the desired result (meaning you can't use the snippet above an just replace $arr1 by $arr2 and vice-versa). You're probably right about the array-definitions though.
Yeah, I just realized that. That forces you to do it this way. It would be better if the arrays, in the question, had proper names, like $payments, $customers, or $orders, that would give you an better idea what you're dealing with.
Thanks, It's work for me. It save second loop time.
It's only work for customer id match, if date are different then it's not work. Please check 3v4l.org/TeTpK
|
1

sometimes things can be done in hard way:)

<?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);

1 Comment

I think that the === triple equals 'Identical Operator' is over the top here. The == double equals 'Equal Operator' will do. I really wouldn't care if an 'id' was 3943 (integer) or "3943" (string), moreso, I would think they are equal and should be seen as such.
1

If you cannot change the layout of the first array I think it will be best to first create an intermediate array that keeps a record of all expire dates for every customer.

The following implementation does not require you to use a nested loop.

<?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);

Result:

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
    )

)

See demo

Comments

1

This can fix the issue :

$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);

the output is similar to what you are looking for :

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)
  }
}

2 Comments

Your $arr2 is not the same as in the question. See the 'paid' keys.
you're right, i jut update my answer , this will not hurt the result . thank you @KIKOSoftware

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.