如何添加两个多维数组的合并子数组

问题描述:

Sorry about such an easy question but I am new to PHP. I am trying to add the isInStock keys and values from this array:

$stock array:

Array
(
    [0] => Array
        (
            [name] => name of item 1
            [price] => 45.00
            [colour] => Neon yellow
            [image] => http://images1
            [url] => http://url1
            [productid] => 7985894
            [variants] => Array
                (
                    [0] => Array
                        (
                            [variantId] => 7986029
                            [isInStock] => 1
                        )
                    [1] => Array
                        (
                            [variantId] => 7986070
                            [isInStock] => 1
                        )
                    [2] => Array
                        (
                            [variantId] => 7985916
                            [isInStock] => 1
                        )
                    [3] => Array
                        (
                            [variantId] => 7985929
                            [isInStock] => 1
                        )

                    [4] => Array
                        (
                            [variantId] => 7985918
                            [isInStock] => 1
                        )
                    [5] => Array
                        (
                            [variantId] => 7985935
                            [isInStock] => 1
                        )
                    [6] => Array
                        (
                            [variantId] => 7985945
                            [isInStock] => 1
                        )
                    [7] => Array
                        (
                            [variantId] => 7985994
                            [isInStock] => 1
                        )
                )
            [productId] => 7985894
        )
    [1] => Array
        (
            [name] => name of item 2
            [price] => 45.00
            [colour] => Multi
            [image] => http://images
            [url] => http://url
            [productid] => 8040851
            [variants] => Array
                (
                    [0] => Array
                        (
                            [variantId] => 8040898
                            [isInStock] => 1
                        )
                    [1] => Array
                        (
                            [variantId] => 8041115
                            [isInStock] => 1
                        )
                    [2] => Array
                        (
                            [variantId] => 8040904
                            [isInStock] => 1
                        )
                    [3] => Array
                        (
                            [variantId] => 8041132
                            [isInStock] => 1
                        )
                    [4] => Array
                        (
                            [variantId] => 8041015
                            [isInStock] => 1
                        )
                    [5] => Array
                        (
                            [variantId] => 8040942
                            [isInStock] => 1
                        )
                    [6] => Array
                        (
                            [variantId] => 8040954
                            [isInStock] => 1
                        )
                    [7] => Array
                        (
                            [variantId] => 8040990
                            [isInStock] => 1
                        )
                )
            [productId] => 8040851
        )

and put them in this array under each size according to the variantId value if they both match.

$data array:

Array
(
    [0] => Array
        (
            [name] => name 1 
            [price] => 45.00
            [colour] => Neon yellow
            [image] => http://url
            [url] => http://url1
            [productid] => 7985894
            [variants] => Array
                (
                    [0] => Array
                        (
                            [variantId] => 7986029
                            [size] => US 0
                        )
                    [1] => Array
                        (
                            [variantId] => 7986070
                            [size] => US 2
                        )
                    [2] => Array
                        (
                            [variantId] => 7985916
                            [size] => US 4
                        )
                    [3] => Array
                        (
                            [variantId] => 7985929
                            [size] => US 6
                        )
                    [4] => Array
                        (
                            [variantId] => 7985918
                            [size] => US 8
                        )
                    [5] => Array
                        (
                            [variantId] => 7985935
                            [size] => US 10
                        )
                    [6] => Array
                        (
                            [variantId] => 7985945
                            [size] => US 12
                        )
                    [7] => Array
                        (
                            [variantId] => 7985994
                            [size] => US 14
                        )
                )
        )
    [1] => Array
        (
            [name] => name 1
            [price] => 45.00
            [colour] => Multi
            [image] => http://url
            [url] => http://url
            [productid] => 8040851
            [variants] => Array
                (
                    [0] => Array
                        (
                            [variantId] => 8040898
                            [size] => US 0
                        )
                    [1] => Array
                        (
                            [variantId] => 8041115
                            [size] => US 2
                        )
                    [2] => Array
                        (
                            [variantId] => 8040904
                            [size] => US 4
                        )
                    [3] => Array
                        (
                            [variantId] => 8041132
                            [size] => US 6
                        )
                    [4] => Array
                        (
                            [variantId] => 8041015
                            [size] => US 8
                        )
                    [5] => Array
                        (
                            [variantId] => 8040942
                            [size] => US 10
                        )
                    [6] => Array
                        (
                            [variantId] => 8040954
                            [size] => US 12
                        )
                    [7] => Array
                        (
                            [variantId] => 8040990
                            [size] => US 14
                        )
                )
        )

I have been trying to solve this for a while now, but I keep getting stuck. I can assign individual values but can't get it to do the whole array. Any help would be appreciated.

I would like my resulting array to be like this:

Array
(
    [0] => Array
        (
            [name] => name 1 
            [price] => 45.00
            [colour] => Neon yellow
            [image] => http://url
            [url] => http://url1
            [productid] => 7985894
            [variants] => Array
                (
                    [0] => Array
                        (
                            [variantId] => 7986029
                            [size] => US 0
                            [isInStock] => 1
                        )    
                    [1] => Array
                        (
                            [variantId] => 7986070
                            [size] => US 2
                            [isInStock] => 1
                        )    
                    [2] => Array
                        (
                            [variantId] => 7985916
                            [size] => US 4
                            [isInStock] => 1
                        )    
                    [3] => Array
                        (
                            [variantId] => 7985929
                            [size] => US 6
                            [isInStock] => 1
                        )    
                    [4] => Array
                        (
                            [variantId] => 7985918
                            [size] => US 8
                            [isInStock] => 1
                        )    
                    [5] => Array
                        (
                            [variantId] => 7985935
                            [size] => US 10
                            [isInStock] => 1
                        )    
                    [6] => Array
                        (
                            [variantId] => 7985945
                            [size] => US 12
                            [isInStock] => 1
                        )    
                    [7] => Array
                        (
                            [variantId] => 7985994
                            [size] => US 14
                            [isInStock] => 1
                        )    
                )    
        )    
    [1] => Array
        (
            [name] => name 1
            [price] => 45.00
            [colour] => Multi
            [image] => http://url
            [url] => http://url
            [productid] => 8040851
            [variants] => Array
                (
                    [0] => Array
                        (
                            [variantId] => 8040898
                            [size] => US 0
                            [isInStock] => 1
                        )    
                    [1] => Array
                        (
                            [variantId] => 8041115
                            [size] => US 2
                            [isInStock] => 1
                        )    
                    [2] => Array
                        (
                            [variantId] => 8040904
                            [size] => US 4
                            [isInStock] => 1
                        )    
                    [3] => Array
                        (
                            [variantId] => 8041132
                            [size] => US 6
                            [isInStock] => 1
                        )    
                    [4] => Array
                        (
                            [variantId] => 8041015
                            [size] => US 8
                            [isInStock] => 1
                        )    
                    [5] => Array
                        (
                            [variantId] => 8040942
                            [size] => US 10
                            [isInStock] => 1
                        )    
                    [6] => Array
                        (
                            [variantId] => 8040954
                            [size] => US 12
                            [isInStock] => 1
                        )    
                    [7] => Array
                        (
                            [variantId] => 8040990
                            [size] => US 14
                            [isInStock] => 1
                        )    
                )    
        )

So far I have tried array_merge which doesn't put the values in the right place. I have tried this $data['isInstock'] = $stock[0]['variants'][0]['variantId']; which also won't work.

Sadly, it takes a fair amount of iterating/preparation to get your two arrays ready for use with array_merge_recursive(). I'll admit, I'm not proud of the convolution in my method. The major factor in all this is that array_merge_recursive() only "plays nicely" with non-numeric indexes, so I had to replace your numerically indexed keys with relative id values within the arrays. I'll do my best to explain my steps, but again, it's not pretty... (Demo)

Step #1: Prepare $stock array:

foreach($stock as $subarray){
    $new_stock["#{$subarray['productid']}"]=$subarray;  // replace outer key
    $new_variants=[];                                   // declare a fresh array
    foreach($subarray['variants'] as $varsub){
        $new_variants["#{$varsub['variantId']}"]['isInStock']=$varsub['isInStock'];  // one element only
        // omitting variantId element this time as the next array will offer it.
    }
    $new_stock["#{$subarray['productid']}"]['variants']=$new_variants;
}

Step #2: Prepare $data array & merge:

foreach($data as $subarray){
    $new_data["#{$subarray['productid']}"]=$subarray;  // replace outer key
    $new_variants=[];                                  // declare a fresh array
    foreach($subarray['variants'] as $varsub){
        $new_variants["#{$varsub['variantId']}"]=$varsub; // both elements from variants
    }
    $new_data["#{$subarray['productid']}"]['variants']=array_values(array_merge_recursive($new_variants,$new_stock["#{$subarray['productid']}"]['variants']));
    // new variants subarray has been merged, re-indexed, and written to $new_data
}

Step #3: re-index outer array keys, and display:

$result=array_values($new_data);    
var_export($result);

The bulk of the array preparations is to generate unique id's for the outer and inner arrays (in both $stock & $data). This permits the array_merge to isolate the related productids and recursively merge the variant elements.

If these two arrays are being generated from a database, then my high recommendation is to utilize available database functionality to merge this data instead of php.

For a simple example of how array_merge_recursive() works here's a small demo. Experiment with the keys in either of the arrays. If you so-much-as remove the # from the numeric string, array_merge_recursive() will assume that it's dealing with numeric indexes and mince things up. My technique to preserve your id's as strings was to prepend the #, but it could have been done by adding any of a range of non-digit characters to the key value.