php - Merge/Replace associative rows from one array with the associative rows of another array

70

I have 2 arrays - one is hard coded and the other is data retrieved from a database. I am trying to merge them but I'm having unexpected results.

This is the first array:

$base_image_array = [
    ["product_image_one" => ""],
    ["product_image_two" => ""],
    ["product_image_three" => ""],
    ["product_image_four" => ""]
];

This is the second array:

$db_product_images = [
    ["product_image_one" => "../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg"],
];

However, when I tryarray_merge($base_image_array, $db_product_images), I get 5 rows and theproduce_image_one occurs more than once.

What I want to achieve is this:

[
    ['product_image_one' => '../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg'],
    ['product_image_two' => ''],
    ['product_image_three' => ''],
    ['product_image_four' => '']
]

I think the multidimensional nature of the arrays is confusing me.

179

Answer

Solution:

clean up your num indexed array to kv array

<?php

$base_image_array = array
(
 array("product_image_one" => ""),
 array("product_image_two" => ""),
 array("product_image_three" => ""),
 array("product_image_four" => "")
);

$db_product_images = array
(
 array("product_image_one" => "../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg"),
);

function kv($a){
    $keys = array_map(current, array_map(array_keys, $a));
    $values = array_map(current, array_map(array_values, $a));

    return array_combine($keys, $values);
}

$base_image_array  = kv($base_image_array);
$db_product_images = kv($db_product_images);

$new_array = array_merge($base_image_array, $db_product_images);
print_r($new_array);

output

Array
(
    [product_image_one] => ../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg
    [product_image_two] =>
    [product_image_three] =>
    [product_image_four] =>
)
810

Answer

Solution:

The problem is that the array keys in both arrays are numeric. If you want one array to overwrite the other you need to get them into a state where the array keys are strings. You could do something like this:

$array_with_four = array(...); // The large array
$new_array_with_four = format_arrays($array_with_four);

$array_with_one = array(...); // The small array
$new_array_with_one = format_arrays($array_with_one);

$merged = array_merge($new_array_with_four, $new_array_with_one); // Your new results

function format_arrays($array) {
    $return_array = array(); // Blank array
    foreach ($array as $child_key => $child_data){
        $return_array[$child_key] = $child_data;
    }
    return $return_array;
}

There are probably better ways to loop through this with the php array functions - but this should get the job done!

642

Answer

Solution:

The solution was very similar to the answer by @Matthew R.

/* Base Array */
$base_image_array = array(
    array('product_image_one' => ''),
    array('product_image_two' => ''),
    array('product_image_three' => ''),
    array('product_image_four' => '')
);

/* Populated Array */
$db_product_images = array(
    array("product_image_one" => "../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg")
);

function format_array($array) {
    $return_array = array();
    foreach ($array as $key => $value) {
        foreach ($value as $k => $v) {
            $return_array[$k] = $v;
        }
    }
    return $return_array;
}

$array1 = format_array($base_image_array);
$array2 = format_array($db_product_images);

$final_array = array_merge($array1, $array2);

echo '<pre>';
    print_r($final_array);
echo '</pre>';

The resulting output was like so:

Array
(
    [product_image_one] => ../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg
    [product_image_two] => 
    [product_image_three] => 
    [product_image_four] => 
)

The final output was actually different to what I originally thought I needed.

834

Answer

Solution:

I recommend directly flattening the result because assuming these subarray keys are unique, there is no benefit to the depth of the data structure. You can unpack the two arrays with... (spread operator) and feed the individualized row data toarray_replace() (orarray_merge()) to achieve the same conceptual result:

Code: (Demo)

var_export(array_replace(...$base_image_array, ...$db_product_images));

Output:

array (
  'product_image_one' => '../wp-content/themes/dosco/images/products_images/355_product_image_one.jpg',
  'product_image_two' => '',
  'product_image_three' => '',
  'product_image_four' => '',
)

If you desperately need to keep the deep structure, you can recreate the initial depth by mapping every associative element as its own row.

var_export(
    array_map(
        fn($v) => (array) $v,
        array_replace(...$base_image_array, ...$db_product_images)
    )
);

People are also looking for solutions to the problem: Get Original Referrer URL from Google Search with PHP?

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.