How can I merge array recursively with a unique key? - php

I create my arrays like this:
foreach ($array as $key => $value) {
$array1[$value->getUuid()][$value->getFields()->getName()] = $value->getContent();
}
The result is array1:
array:2 [▼
"d8ab80f4f6" => array:16 [▶]
9087785727 => array:16 [▶]
]
I create another array in a little bit different way, array2:
array:2 [▼
"d8ab80f4f6" => array:3 [▶]
9087785727 => array:3 [▶]
]
Now I want to merge those arrays:
$output = array_merge_recursive($array1,$array2);
The output is:
array:3 [▼
"d8ab80f4f6" => array:19 [▶]
0 => array:3 [▶]
1 => array:16 [▶]
]
But I expect the output to be:
array:3 [▼
"d8ab80f4f6" => array:19 [▶]
"9087785727" => array:19 [▶]
]

array_merge and array_merge_recursive treat string keys differently from numeric keys:
If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended.
That's what's happening here. The key 9087785727 is numeric, so those entries are not being merged.
So you need to write your own loop.
$output = [];
foreach ($array1 as $key => $value) {
$output[$key] = array_merge($value, $array2[$key]);
}
DEMO

You can use next foreach loop with reference &:
foreach($ar1 as $key=>&$subar){
$subar = array_merge($subar,$ar2[$key]);
}
Demo

Related

How to update a nested value within a nested Laravel collection

I have a deployments Laravel Collection like this:
Illuminate\Support\Collection {#415 ▼
#items: array:5 [▼
0 => array:7 [▼
"id" => 31
"status" => "active"
"name" => "Deployment 1"
"spots" => array:4 [▼
0 => array:2 [▼
"id" => 33
"status" => "active" <-- Want to change this
]
1 => array:2 [▶]
2 => array:2 [▶]
3 => array:2 [▶]
]
"data" => array:3 [▶]
]
1 => array:7 [▶]
2 => array:7 [▶]
3 => array:7 [▶]
4 => array:7 [▶]
]
}
I want to update the nested status value to inactive. I have used the Laravel map function, but it only seems to work on collections that have one nesting level. So this...
$this->deployments->map(function ($deployment) {
$deployment['spots'][0]['status'] = 'inactive';
});
dd($this->deployments);
...leaves $this->deployments untouched.
Also tried using nested map functions obtaining a Call to a member function map() on array exception on second level as second and next nesting levels are considered arrays...
Any thoughts?
Thanks in advance.
With the map method, you are almost there. You will have to return the change made in $deployment and do an ->all() at the end to update the collection with the modified values.
For updating a single spot:
$deployments = $deployments->map(function($deployment){
$deployment['spots'][0]['status'] = 'inactive';
return $deployment;
})->all();
For updating all spots:
$deployments = $deployments->map(function($deployment){
foreach($deployment['spots'] as &$spot){
$spot['status'] = 'inactive';
}
return $deployment;
})->all();
For anyone researching this, a more elegant solution might be:
For updating a single spot:
$data = $deployments->all();
$deployments = data_set($data, 'spots.0.status', 'inactive');
For updating all spots:
$data = $deployments->all();
$deployments = data_set($data, 'spots.*.status', 'inactive');

How can I prevent a loop to create keys without quotes?

This is my loop:
foreach ($array as $key => $value) {
$array1[$value->getUuid()][$value->getFields()->getName()] = $value->getContent();
}
The result is:
array:2 [▼
"d8ab80f4f6" => array:16 [▶]
9087785727 => array:16 [▶]
]
I do not understand, why the last key does not have quotes. How can I prevent this?

Unable to add 2 associative arrays

I am trying to add 2 associative arrays, but the new array only comes with an index for the second array.
This is what I am doing
$array = ['name' => 'address', 'value' => 'us'];
$arr = ['name' => 'joe', 'value' => 'doe'];
$arr[] = $array;
This is the result
array:3 [▼
"name" => "joe"
"value" => "doe"
0 => array:2 [▶]
]
I am expecting something like this
array:2 [▼
0 => array:2 [▶]
1 => array:2 [▶]
]
As you can see, there is no index for the first array, thus making the count 3 instead of 2. Please how do I fix this?
Just create another array and add the 2 arrays to it:
$newAr = [];
$newAr[] = $array;
$newAr[] = $arr;
var_dump($newAr);

Problem Iterating through a multi-dimensional array in PHP

Working on a Laravel application whereby I am consuming some data from an API. I get the response as a JSON object and convert to array. It appears as a complex multi-dimensional array
(nested arrays). Am trying to loop through it using a nested foreach so as to reach out to the id of each item but I keep failing..
The response is stored in a variable called usmDet
The array response
array:1 [▼
0 => array:1 [▼
0 => array:3 [▼
"id" => "74696"
"agents" => array:13 [▶]
"policies" => array:481 [▶]
]
1 => array:3 [▼
"id" => "1525"
"agents" => array:8 [▶]
"policies" => array:357 [▶]
]
]
1 => array:1 [▼
0 => array:3 [▼
"id" => "73401"
"agents" => array:1 [ …1]
"policies" => array:8 [ …8]
]
1 => array:3 [▼
"id" => "210"
"agents" => array:13 [ …13]
"policies" => array:773 [ …773]
]
]
]
My nested foreach
foreach($usmDet as $key => $value){
if(is_array($value)){
foreach($value as $key => $value){
echo $key." ".$value."<br>";
}
}
echo "<br>";
}
The id is part of the array, as you can access it like $value['id']
In the second foreach to prevent confusion you should select a different name for the key and the value.
Try it like this:
foreach($usmDet as $key => $value){
if(is_array($value)){
foreach($value as $k => $v){
echo $v['id'] . "<br>";
}
}
}
Result:
74696
1525
73401
210
Php demo
To get all the values for key "id" when multiple nested arrays, you could use array_walk_recursive
$ids = [];
array_walk_recursive($usmDet, function($value, $key) use (&$ids){
if ($key === "id") {
$ids[] = $value;
}
});
print_r($ids);
Php demo

to to get data from specific index in multidimensional array to avoid use of many foreach loops

I am trying to get data in from multidimensional array without using foreach
i tried using in_array() function but not worked
$abc = array()
in_array($abc , $private_job->cities)
in_array() expects parameter 2 to be array, string given
on using $private_job->cities got the following result
Collection {#408 ▼
#items: array:2 [▼
0 => city {#416 ▼
+wasRecentlyCreated: false
#attributes: array:2 [▼
"id" => 7
"city_name" => "Gujranwala"
]
}
1 => city {#417 ▼
+wasRecentlyCreated: false
#attributes: array:2 [▶]
#original: array:4 [▼
"id" => 4
"city_name" => "Islamabad"
"pivot_private_jobabd_id" => 53
"pivot_city_id" => 4
]
}
]
}
whereas i am interested in getting
"id" => 7
"id" => 4
in an an array
$result = $private_job->cities->map(function($data){
return $data['id'];
})->all();

Categories