array_merge function doesn't work properly in Laravel - php

In my project i'm split an array index value based on regex value. but when i want merge all array together the merge function doesn't merge.
Here is my code sample.
$testarray=array();
$merge_array=array();
//receive parameter is Admin|Manager,User#Test
foreach ($roles as $value) {
if(preg_match("/[##%$|:\s,]+/",$value))
{
$testarray=preg_split("/[##%$|:\s,]+/",$value);
}
print_r(array_merge($merge_array,$testarray));
}
The print_r show this result.
Array ( [0] => Admin [1] => Manager ) Array ( [0] => User [1] => Test )

You just merge arrays, but don't assign results to any variable, proper code is:
//receive parameter is Admin|Manager,User#Test
foreach ($roles as $value) {
if(preg_match("/[##%$|:\s,]+/",$value))
{
$testarray=preg_split("/[##%$|:\s,]+/",$value);
}
// here you add $testarray values to
// `$merge_array` on each iteration
$merge_array = array_merge($merge_array,$testarray);
}
// print result array after loop
print_r($merge_array);

The Laravel framework has nothing to do with your issue. You're using PHP's standard functions.
The array_merge function doesn't modify the array you provide to it but provides the resulting array as its output. So you should assign array_merge's result to $merge_array.
Please try the following code:
$testarray = array();
$merge_array = array();
//receive parameter is Admin|Manager,User#Test
foreach ($roles as $value) {
if(preg_match("/[##%$|:\s,]+/",$value))
{
$testarray = preg_split("/[##%$|:\s,]+/",$value);
}
$merge_array = array_merge($merge_array, $testarray);
}
print_r($merge_array);

You seem to think wrong.
print_r(array_merge($merge_array,$testarray));
The above line is in "foreach" loop.
In that case, to get a merged result, you should do like the followings;
$merge_array = array_merge($merge_array,$testarray)
In your code, $merge_array remains empty, so you see the current result.

Related

PHP - Merge append multiple json arrays

I need to merge/join multiple json string that contains arrays (which also need to be merged) but I don't know what is the best way to achieve this :
Initial array of json strings (called $rrDatas in my example below):
Array
(
[0] => {"asset":[1],"person":[1]}
[1] => {"asset":[2]}
)
Expected result :
{"asset":[1,2],"person":[1]}
The main difficulty is that the number of arrays is undefined (my example is made with 2 arrays but it could be 3,4 etc.). The second difficulty is that there can be multiple properties (like "asset", "person" etc. however always arrays). These possible properties are known but are many so it would be better if the algorithm is dynamic.
What I am able to do at the moment :
$mergedAssets['asset'] = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
$mergedAssets['asset'] = array_merge($mergedAssets['asset'],$rrDataJson['asset']);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);
Result :
{"asset":[1,2]}
This works well but this is not dynamic, should I duplicate this part for each possible properties (i.e. "person", etc.) ?
Thanks,
Guillaume
Edit : Brett Gregson's and krylov123's answers below helped me build my own solution which is a mix between both suggestion:
$mergedJson = [];
foreach ($rrDatas as $rrData)
{
$rrDataJson = \GuzzleHttp\json_decode($rrData, true);
foreach(array_keys($rrDataJson) as $property)
{
$mergedJson[$property] = array_merge($mergedJson[$property] ?? [], $rrDataJson[$property]);
}
}
return \GuzzleHttp\json_encode($mergedJson, true);
Find below a better example :
$rrDatas = Array (
[0] => {"asset":[1,2],"person":[1],"passive":[1]}
[1] => {"asset":[3],"charge":[1],"passive":[2]}
)
Which must result in :
{"asset":[1,2,3],"person":[1],"passive":[1,2],"charge":[1]}
Edit 2 : I have just tried Progrock's solution and it seems to work perfectly as well : https://3v4l.org/7hSqi
You can use something like:
$output = []; // Prepare empty output
foreach($rrDatas as $inner){
foreach($inner as $key => $value){
$output[$key][] = $value;
}
}
echo json_encode($output); // {"asset":[1,2],"person":[1]}
Which should give you the desired output. This should work regardless of the keys within the individual arrays and even with empty arrays.
Working example here
Another example with more arrays and more keys and empty arrays
<?php
$array =
[
'{"asset":[1],"person":[1]}',
'{"asset":[2]}',
];
$array = array_map(function($v) { return json_decode($v, true);}, $array);
$merged = array_merge_recursive(...$array);
print json_encode($merged);
Output:
{"asset":[1,2],"person":[1]}
You need to use foreach ($array as $key => $value) iteration, to be able to dynamicaly use keys of your json array (e.g. "asset" and "person").
Solution:
$mergedAssets['asset'] = [];
foreach ($rrDatas as $key => $value)
{
$rrDataJson = \GuzzleHttp\json_decode($value, true);
$mergedAssets[$key] = array_merge($mergedAssets[$key],$rrDataJson[$key]);
}
$result = \GuzzleHttp\json_encode($mergedAssets, true);

How to loop(foreach) json decoded in php (laravel)

This is my code`
$a =json_decode($user->name, true);
And I need to loop $a, but I'm getting
"Invalid Argument supplied for foreach"
while executing
`
you can loop in array and i think the result of this $a =json_decode($user->name, true);
is string
Based on what you've posted in the other answer and the comment to me, you need to change your loop to this:
foreach($a[0] as $akey => $aloop) { array_push($array, $aloop->email)); }
Notice the change from $a to $a[0]
You should describe to us how your JSON String look like.
Maybe you can try this code below :
$user= '[{"name":"Jonathan Suh","email":"jonathan.suh#gmail.com"},
{"name":"William Phil","email":"will.phil#gmail.com"},
{"name":"Allison Kin","email":"allison.kin#gmail.com"}]';
// Replace with your own JSON
$a = json_decode($user, true); // Array
// Create empty array to hold query results
$array = [];
// Begin loop ( foreach )
foreach ($a as $akey => $aloop) {
array_push($array, ['name' => $aloop["name"], 'email' => $aloop["email"]]);
}
// Encode your array result from Loop Process to JSON
// You can change whatever you want to do from your Result Loop
$jsonENC = json_encode($array);
// You know what is this...
echo $jsonENC;

return data using variable variables

$raw_data = array ('data' => array ('id' => 'foo'));
$fields = array ('id_source' => "data['id']");
foreach ($raw_data as $data) {
foreach ($fields as $key => $path) {
var_dump ($data['id']);
var_dump ($$path);
}
}
The first var_dump gives me the correct value of foo. However, the second one gives me Undefined variable: data['id']. Can anyone tell me why that would be the case, especially since the first var_dump worked confirming the variable $data['id'] is set.
I realized this example is basic and I could just do $data[$key] and change $fields = array ('id_source' => 'id'); but I want to be able to go deeper into the multidimensional arrays when needed. That is why I'm trying to do my original approach.

is_array returning FALSE when array is provided

I'm trying to convert a multidimensional object into an array to pass into an API call that requires an array. Problem is, even after converting the object to array using the lazy method of:
$data = json_decode(json_encode($object),true)
The returned value is acting funny. I'm getting empty array values where values should be none, so I tried running it through a foreach loop:
foreach ( $data as $key => $data_each ) {
if ( is_array($data_each[$key]) ) { $data[$key] = NULL; }
}
But it's not catching the array value in the foreach loop. After running the foreach, I check the value that I happen to KNOW is coming back as an empty array and as long as I check using in_array outside the foreach loop is is catching it as an array. But not within the loop for some reason.
What am I missing?
You have this:
foreach ( $data as $key => $data_each ) {
if ( is_array($data_each[$key]) ) { $data[$key] = NULL; }
}
Here, $data_each is a value of $data[$key]. Try is_array($data_each) if you want to check whether the value is an array or not. In the loop $data_each is same as $data[$key].

Adding key=>value pair to existing array with condition

Im trying to add a key=>value to a existing array with a specific value.
Im basically looping through a associative array and i want to add a key=>value foreach array that has a specific id:
ex:
[0] => Array
(
[id] => 1
[blah] => value2
)
[1] => Array
(
[id] => 1
[blah] => value2
)
I want to do it so that while
foreach ($array as $arr) {
while $arr['id']==$some_id {
$array['new_key'] .=$some value
then do a array_push
}
}
so $some_value is going to be associated with the specific id.
The while loop doesn't make sense since keys are unique in an associative array. Also, are you sure you want to modify the array while you are looping through it? That may cause problems. Try this:
$tmp = new array();
foreach ($array as $arr) {
if($array['id']==$some_id) {
$tmp['new_key'] = $some_value;
}
}
array_merge($array,$tmp);
A more efficient way is this:
if(in_array($some_id,$array){
$array['new_key'] = $some_value;
}
or if its a key in the array you want to match and not the value...
if(array_key_exists($some_id,$array){
$array['new_key'] = $some_value;
}
When you use:
foreach($array as $arr){
...
}
... the $arr variable is a local copy that is only scoped to that foreach. Anything you add to it will not affect the $array variable. However, if you call $arr by reference:
foreach($array as &$arr){ // notice the &
...
}
... now if you add a new key to that array it will affect the $array through which you are looping.
I hope I understood your question correctly.
If i understood you correctly, this will be the solution:
foreach ($array as $arr) {
if ($arr['id'] == $some_id) {
$arr[] = $some value;
// or: $arr['key'] but when 'key' already exists it will be overwritten
}
}

Categories