0

My goal is to be able to update a key value inside of an array inside of an array and I'm don't know if I'm using the right php array function.

BEFORE:

array:2 [
    "week_number" => 1
    "games" => array:1 [
        0 => array:3 [
            "game_number" => 1
            "umpires" => []
            "teams" => []  
        ]
    ]
]

AFTER:

array:2 [
    "week_number" => 1
    "games" => array:1 [
        0 => array:3 [
            "game_number" => 1
            "umpires" => []
            "teams" => [1,2]  
        ]
    ]
]

Test Class:

private function validParams($overrides = [])
{
    return array_merge_recursive([
        'week_number' => 1,
        'games' => [[
            'game_number' => 1,
            'umpires' => [],
            'teams' => [], 
        ]]
    ], $overrides);
}


$response = $this->actingAs($this->authorizedUser)
                    ->post(route('games.store', ['week' => $this->week->id]), $this->validParams([
                        'games' => [][
                            [
                                'teams'  => [1,2]
                            ]
                        ]
                    ]));
user3732216
  • 1,579
  • 8
  • 29
  • 54

3 Answers3

1

If you want to update the keys... typing $array['new_key'] = $array['old_key'] will duplicate the value with 2 sets of keys.

You have a few options here. Either you create a new array and just set your desired keys or work with array_keys and array_values and mix them up... your choice

http://php.net/manual/en/ref.array.php

See the list above, there are a lot of array functions you can use... see the two above and array_map... there is virtually a great number of ways you can do this. See how your problem is best handled after reviewing the documentation.

Good luck!

ied3vil
  • 964
  • 1
  • 7
  • 18
  • So you are saying that I can't replace the existing key value. – user3732216 Jun 09 '18 at 17:31
  • Not literally replace, you just have to process the data differently in order to obtain your desired result. Simplest way is to do a foreach on the new array, have your conditions there and populate a new array with the new keys, using the values from the initial array. That's how i'd do it, i guess – ied3vil Jun 09 '18 at 17:33
  • Is it because I have an array inside of an array because I have other tests that work fine with just array_merge with setting values. – user3732216 Jun 09 '18 at 17:40
  • Without a proper example i can't help more... however i suggest going and digging into the solutions provided by me and others and learn how arrays work... you can easily replace values, but to add new keys it will also keep old value, there is no real way to "change" a key, that is how it is designed – ied3vil Jun 09 '18 at 17:57
1

This is the moment where you need unset(): Adding a value with a different key will not update or overwrite the old value but simply add another key-value pair. Hence, add the new value fist, then unset the old one. We can use To array_walk to itterate over the array:

array_walk($array, function (& $item) {
   $item['new_key'] = $item['old_key'];
   unset($item['old_key']);
});

Take note of the & reference operator in the lambda function: it ensures we are working on the original array and not a copy of it.

wp78de
  • 18,207
  • 7
  • 43
  • 71
  • This can lead to the interesting problem that if you change a key to an already existing key that this value will be overwritten and then possibly copied when the overwritten item is renamed. See the duplicate flagged for more problems. – Nigel Ren Jun 09 '18 at 17:45
  • Yes, this may be a too simplistic solution if the order, existing keys, and other things have to be taken into account. – wp78de Jun 09 '18 at 17:51
0

I found this as a solution.

private function validParams($overrides = [])
{
    return array_replace_recursive([
        'week_number' => 1,
        'games' => [
            0 => [
                'game_number' => 1,
                'umpires' => [],
                'teams' => [],
            ]
        ]
    ], $overrides);
}


->post(route('games.store', ['week' => $this->week->id]), $this->validParams([
    'games' => [
        0 => [
            'teams'  => [1,2]
        ]
                        ]
    ]));
user3732216
  • 1,579
  • 8
  • 29
  • 54