简体   繁体   中英

How to combine or merge two nested arrays according to their index

Here is the formatted code:

<?php
$final_data1 = [
    '6882' => [
            'observation' => '51',
            'dom' => '4462',
            'amenity_value' => '5900',
            'amenity_id' => '6882',
            'amenity_name' => '10 ft. Ceiling',
            'unit_id' => [
                    '0' => '45349',
                    '1' => '45350',
                ]
        ],
    '6842' => [
            'observation' => '0',
            'dom' => '0',
            'amenity_value' => '0',
            'amenity_id' => '6842',
            'amenity_name' => '11 Ft. Ceiling',
            'unit_id' => [
                    '0' => '45317',
                    '1' => '45531'
                ]
        ]

];
$final_data2 =  [
    '6882' => [
            'observation' => '5',
            'dom' => '415',
            'amenity_value' => '150',
            'amenity_id' => '6882',
            'amenity_name' => '10 ft. Ceiling',
            'unit_id' => [
                    '0' => '45502',
                    '1' => '45505',
                    '2' => '45786'
                ]
        ]
];
$final_data  = [
    '6882' => [
            'observation' => '56', //51+5 = 56
            'dom' => '4877', //4462+415 = 4877
            'amenity_value' => '6050', //5900+150
            'amenity_id' => '6882',//no addition here id fixed
            'amenity_name' => '10 ft. Ceiling', //name fixed too
            'unit_id' => [
                    '0' => '45349',
                    '1' => '45350',
                    '2' => '45502',
                    '3' => '45505',
                    '4' => '45786' //here concatenated the two array $final_data1['6882']['unit_id'] and $final_data2['6882']['unit_id']
                ]
        ],
    '6842' => [
            'observation' => '0',
            'dom' => '0',
            'amenity_value' => '0',
            'amenity_id' => '6842',
            'amenity_name' => '11 Ft. Ceiling',
            'unit_id' => [
                    '0' => '45317',
                    '1' => '45531'
                ]
        ]

];
print_r($final_data);

Here, you can see I have two array $final_data1 and $final_data2 where first one has two index and second one as one index. Now, I want combine this two arrays to one $final_data . While combining we need to consider only those value with same index.

In this case, we will add $final_data1['6882'] and $final_data2['6882'] but index 6842 is present only in $final_data1 so this will be same in $final_data .

And, while producing final results we need to sum observation, dom, amenity_value , while amenity_id, amenity_name should be used as fixed value and unit_id should be merged or concatenated. To make this more clear I have commented it on $final_data which is the expected output.

I have tried with $final_data = $final_data1 + $final_data2 but it does not seems working.

In case you need phpsandbox online url

Update:

I achieved the desired result as follows:

        $final_key1 = array_keys($final_data1);
        $final_key2 = array_keys($final_data2);
        $final_keys = array_unique(array_merge($final_key1,$final_key2));

        foreach($final_keys as $fk){
            $obser1 = $obser2 = $dom1 = $dom2 = $a_val1 = $a_val2 = 0;
            $a_id = 0;
            $a_name = '';
            $u_ids1 = $u_ids2 = [];
            if(isset($final_data1[$fk])){
                $obser1 = $final_data1[$fk]['observation'];
                $dom1 = $final_data1[$fk]['dom'];
                $a_val1 = $final_data1[$fk]['amenity_value'];
                $a_id =  $final_data1[$fk]['amenity_id'];
                $a_name =  $final_data1[$fk]['amenity_name'];
                $u_ids1 = $final_data1[$fk]['unit_id'];
            }
            if(isset($final_data2[$fk])){
                $obser2 = $final_data2[$fk]['observation'];
                $dom2 = $final_data2[$fk]['dom'];
                $a_val2 = $final_data2[$fk]['amenity_value'];
                if(empty($a_id)){
                    $a_id = $final_data2[$fk]['amenity_id'];
                    $a_name = $final_data2[$fk]['amenity_name'];
                }
                $u_ids2 = $final_data2[$fk]['unit_id'];

            }

            $final_data[$fk]['observation'] = $obser1 + $obser2;
            $final_data[$fk]['dom'] = $dom1 + $dom2;
            $final_data[$fk]['amenity_value'] = $a_val1 + $a_val2;
            $final_data[$fk]['amenity_id'] = $a_id;
            $final_data[$fk]['amenity_name'] = $a_name;
            $final_data[$fk]['unit_id'] = array_merge($u_ids1,$u_ids2);
        }

But, is there any cleaner way than this?

Well it's not "cleaner" I think, but this is my version ( ;) ):

$goal = array(); // What you want
$uids = array(); // Well idk what you want to do exactly... Ill seperate them then :P
$arrayOfArrayOfArrays = array($final_data1, $final_data2);
foreach ($arrayOfArrayOfArrays as $arrayOfArray) {
    foreach ($arrayOfArray as $key0 => $val0) {
        if (!is_array($val0)) { continue; } // true I know ... but just for... well you know :-°
        $flag = true;
        foreach ($val0 as $key1 => $val1) {
            if ($key1 === "unit_id" && is_array($val1)) {
                foreach ($val1 as $key2 => $val2) {
                    $uids[] = $val2;
                }
            }
            foreach ($goal as $key => $val) {
                if ($key === $key0) {
                    $flag = false;
                    break; // don't forget to have a break. For microtime and kitkat 8-)
                }
            }
            if (!$flag) {
                if (
                    $key1 === "observation" ||
                    $key1 === "dom" ||
                    $key1 === "amenity_value"
                ) {
                    $goal[$key0][$key1] += $val1;
                }
            }
        }
        if ($flag) { $goal[$key0] = $val0; }
    }
}
foreach ($goal as $theKey => $iWantToDelete) {
    foreach ($iWantToDelete as $uid => $hmpf) {
        if ($uid === "unit_id") {
            unset($goal[$theKey][$uid]);
            break;
        }
    }
}
$goal["unit_ids"] = r_ids($uids);
unset($uids);
function r_ids ($array, $flat=false) {
    if (!is_array($array) || empty($array)) { return $array; }
    if (empty($flat)) { $flat = array(); }
    foreach ($array as $key => $val) {
        if (is_array($val)) { $flat = r_ids($val, $flat); }
        else { $flat[] = $val; }
    }
    return $flat;
}
print_r($goal);

Funny thing. Idk what to do with the id array.. ;)

http://sandbox.onlinephpfunctions.com/code/69cbe9cddb5ae1f593d332d488eaa31c88eaa915

Good luck and regards

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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