0

I would like to change the values in one multidimensional array if a corresponding key is found in another flat, associative array.

I have these two arrays:

$full = [
    'Cars' => [
         'Volvo' => 0,
         'Mercedes' => 0,
         'BMW' => 0,
         'Audi' => 0
    ],
    'Motorcycle' => [
        'Ducati' => 0,
        'Honda' => 0,
        'Suzuki' => 0,
        'KTM' => 0
    ]
];

$semi = [
    'Volvo' => 1,
    'Audi' => 1
];

I want the array to look like this:

Array
(
    [Cars] => Array
        (
            [Volvo] => 1
            [Mercedes] => 0
            [BMW] => 0
            [Audi] => 1
        )

    [Motorcycle] => Array
        (
            [Ducati] => 0
            [Honda] => 0
            [Suzuki] => 0
            [KTM] => 0
        )
)

I get the $semi array back from my input field and want to merge it into $full to save it into my database.

I already tried array_replace() like:

$replaced = array_replace($full, $semi);
5
  • What if... Honda is both a car and a motorcycle, how would you know where to add it? Commented Jul 1, 2022 at 9:19
  • Those are just dummy values, normally, we have distinct values. Just changed it for the question here Commented Jul 1, 2022 at 9:20
  • The problem with accepting an answer too quickly is that you decrease the incentive for other contributor to add alternative answers. Please always present array data as var_export so that contributors can instantly use your data in their sandboxes. Now I have to waste my time retyping your input on my phone before I can test my suggested code. Commented Jul 1, 2022 at 9:39
  • @mickmackusa my bad, sorry Commented Jul 1, 2022 at 9:46
  • This might be an XY Problem. If you explain how your database table is configured, we may be able to avoid this whole task and just send this user-supplied data directly to your table with a well-crafted UPDATE query. Commented Jul 1, 2022 at 10:14

2 Answers 2

1

You should loop your $semi array and check if it exists in one of $full arrays, then add to it:

foreach ($semi as $semiItem => $semiValue) {
    foreach ($full as &$fullItems) {
        if (isset($fullItems[$semiItem])) {
            $fullItems[$semiItem] = $semiValue;
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

is it also possible to set all other values = 0 that are not in the $semi array?
0

You only need to visit "leafnodes", it will be very direct to iterate and modify the full array with array_walk_recursive().

Modern "arrow function" syntax allows access to the semi array without writing use().

This approach makes absolutely no iterated function calls. It modifies $v by reference (&$v), uses the "addition assignment" combined operator (+=), and the null coalescing opetator (??) to conditionally increase values in the full array which are found in the semi array.

Code: (Demo)

array_walk_recursive(
    $full,
    fn(&$v, $k) => $v += $semi[$k] ?? 0
);

var_export($full);

Not using array_walk_recursive() would necessitate using nested loops to increase qualifying manufacturers.

Code: (Demo)

foreach ($full as &$manufacturers) {
    foreach ($manufacturers as $m => &$count) {
        $count += $semi[$m] ?? 0;
    }
}
var_export($full);

1 Comment

If you are merely overwriting the counts (not adding them), you can use = instead of +=.

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.