How to combine 2 arrays based on same value of same key - php

I want to merge/combine 2 arrays based on the same key/value pair.
To be more clear, what I'm searching for is kind of a join function known in MySQL. The first array should be "joined" by the second one, based on the ID, which is the key/value pair 'name'.
How can I do this?
1. ARRAY
[0] => Array
(
[name] => first
[logo] => url
[cat] => abc
)
[1] => Array
(
[name] => second
[logo] => url
[cat] => abc
)
2. ARRAY
[0] => Array
(
[name] => first
[menu] => true
[key] => value
)
NEW ARRAY (Expexted Result):
[0] => Array
(
[name] => first
[logo] => url
[cat] => abc
[menu] => true
[key] => value
)
As you an see, it's quite self-explaining. In this case, the 'name' key is like an ID (for both arrays).

If you reindex your second array by name first, it will be easier to get those values from it.
$second = array_column($second, null, 'name');
(It's okay to do this if 'name' is unique in the array. I assume that's the case since you said it's "like an ID". If 'name' isn't unique then you'll lose some rows when you reindex, because array keys have to be unique.)
Then iterate your first array and merge any corresponding values in the second array into the result.
foreach ($first as $key => $value) {
if (isset($second[$value['name']])) {
$result[$key] = array_merge($value, $second[$value['name']]);
}
}
This would be like an inner join in SQL, where the result would only include rows where the value exists in both tables. If you wanted it to work more like a left join, then you'd need to merge a set of empty values for the keys in the second array if a matching name value wasn't found there.
foreach ($first as $key => $value) {
if (isset($second[$value['name']])) {
$result[$key] = array_merge($value, $second[$value['name']]);
} else {
$result[$key] = array_merge($value, ['menu' => null, 'key' => null]);
}
}
Working example at 3v4l.org.

Try this
$mergedArray = array_merge_recursive ($firstArray,$secondArray);
$newArray = [];
foreach( $mergedArray as $subArr ) {
$newArray = array_merge($subArr,$newArray);
}

Related

Ordering an array which is inside of another array based in an array keys order

Im exporting a grid to xls, I have an array $data which holds the informations inside of a numeric array, like:
Array
(
[0] => Array
(
[Field1] => "Value"
[Field2] => "Different value"
[Field3] => "Another alue"
)
)Where [0] is the first line of the grid (and the grid can have up to 10k lines or just 3)
But the user can change the order of the fields or add more (or even hide the ones is on the grid), so I have another array which holds exactly which Fields are visible and their current orders "$currentOrder" (both arrays - the numeric one inside $data and $currentOrder - have the same amount and name of keys).
I've been having trouble to get inside the numeric array and order it's field like $currentOrder's (and change the values to the right field)
If my $currentOrder isArray
(
[Field3] => ""
[Field1] => ""
[Field2] => ""
)
My $data output have to be
Array
(
[0] => Array
(
[Field3] => "Another value"
[Field1] => "Value"
[Field2] => "Different Value"
)
)
This should do what you want. It uses array_map to reorder each element of $data according to the key order in $current_order.
$data = array(array('Field1'=>'Value',
'Field2'=>'Different value',
'Field3'=>'Another value')
);
$currentOrder = array('Field3'=>'',
'Field1'=>'',
'Field2'=>'');
$output = array_map(function ($arr) use ($currentOrder) {
$newarr = array();
foreach (array_keys($currentOrder) as $key)
$newarr[$key] = $arr[$key];
return $newarr;
}, $data);
print_r($output);
Output:
Array
(
[0] => Array
(
[Field3] => Another value
[Field1] => Value
[Field2] => Different value
)
)
Use Like It:-
foreach($urarr as $key => $val){
ksort($urarr[$key], SORT_NUMERIC);
}

Find value in Multidimensional array by array of keys

I am working on a script that lets the user load a remote XML file and lets them choose an element. I then need to be able to retrieve the value of that element a later date. The XML is updated regularly and I want to display the updates value each time.
So far I convert the XML into a multidimensional array, display the elements and their values to the user, and when they choose an element I save the keys of the multidimensional array.
So for example if we have the following array:
Array
(
[responsecode] => 0
[message] =>
[items] => Array
(
[0] => Array
(
[title] => Example1
[content] => This is the first message
[date] => 00/00/00
)
[1] => Array
(
[title] => Example2
[content] => This is the second message
[date] => 00/00/00
)
)
)
If the user chooses the first title element I save the path as follows:
$path = "itmes>0>title";
I then explode the string to get the separate keys:
$keys = explode(">", $path);
Array
(
[0] => items
[1] => 0
[2] => title
)
If I wanted to read the value manually I would use:
array['items']['0']['title']
But how would I build that query when I have an array of they keys?
Just write a loop:
function extract_value(array $array, array $keys) {
foreach($keys as $key) {
if (!isset($array[$key])) return null;
$array = $array[$key];
}
return $array;
}
You would use this as in
$result = extract_value($data, $keys);
The idea is that you have a variable that "points to" an element in the array, and you update it by branching with each key value. When there are no more keys the pointer points to your result.

Most Efficient Way to Delete Nested Array Element

Say I have the following:
Array(
[0] => Array
(
[id] => 1
[item] => first item
)
[1] => Array
(
[id] => 3
[item] => second item
)
[2] => Array
(
[id] => 5
[item] => third item
)
)
I want to delete the item with id = 5. I know I can loop through the array and unset, but I'm hoping for a more direct/efficient solution.
If you cannot make the IDs the keys of the outer array (then you could simply use unset($arr[5]);), looping over the array is indeed the way to dg.
foreach($arr as $key => $value) {
if($value['id'] === 5) {
unset($arr[$key]);
break;
}
}
Another option would be using array_filter - that's less efficient though since it creates a new array:
$arr = array_filter($arr, function($value) {
return $value['id'] !== 5;
});
Why don't you create the array with the keys set as the ID's? E.g:
Array(
[1] => Array
(
[id] => 1
[item] => first item
)
[3] => Array
(
[id] => 3
[item] => second item
)
[5] => Array
(
[id] => 5
[item] => third item
)
)
You can then write:
<?php
unset($array[5]); // Delete ID5
?>
For Multi level nested array
<?php
function remove_array_by_key($key,$nestedArray){
foreach($nestedArray as $k=>$v){
if(is_array($v)){
remove_array_by_key($key,$v);
} elseif($k==$key){
unset($nesterArray[$k]);
}
}
return $nestedArrat;
}
?>
The most efficient way would be to have 2 arrays.
ID => Index
Index => Object (your current array)
Search for ID in your ID => Index helper array and the value will be the Index for your main array, then unset them both.

Multiple foreach loops and accessing values outside

I'm trying to access multiple values in multiple foreach loops outside of the loops:
foreach(array1 as arr1) {
$var1 = arr2['value1']; //$array is associative array with mutliple keys value1
}
Then I have another
foreach(array2 as arr2) {
$var2 = arr2['value']; //$array2 is another associative array with multiple keys value
}
All of this is within another big foreach loop and now I want to create an array within the big foreach with $var1 and $var2 being used. This array I'm going to be creating is going to be an associative array as well. Any ideas how I can do this?
Array 1:
Array
(
[0] => Array
(
[id] => 1
[id_name] => 251452
[name] => bob
)
[1] => Array
(
[id] => 2
[id_name] => 251453
[name] => bob
)
)
Array 2:
Array
(
[0] => Array
(
[id_person] => 4
[id_last_name] => 251452
[last_name] => smith
)
[1] => Array
(
[id_person] => 15
[id_last_name] => 251453
[last_name] => johnson
)
)
Assume these come from two different queries from the database.
I want to get the first name from the first array for each one and get the last name from the second array for each one and make one array that has this data along with others.
Have a look into multi dimensional arrays.
Also have a look at stdclass and maybe creating an array of these which can store many variables within a single definition - which can help in many ways. (standard class)
Nested looping - this would just dump all sub arrays into an object
// Object and array examples for an InnerArray
$Object = new stdclass();
$AllOfIt = array();
$cnt = 0;
foreach($OuterArray as $OuterKey => $InnerArray)
{
$cnt++;
foreach($InnerArray as $InnerKey => $InnerValue)
{
$Object->$cnt = $InnerValue;
$AllOfIt[$cnt] = $InnerValue;
}
}

Find key of parent in array / PHP

Perhaps someone can help me out with this one:
I'm using a basic search function to find an array deep within an array. The problem is, once that array is found, I'd also like to return it's parent key.
Is there a PHP function that can determine the parent key of an array?
Below is an example of the Search Function... Ideally I'd like to return the array that is found, as well as it's parent key.
function search($array, $key, $value){
$results = array();
if (is_array($array)){
if ($array[$key] == $value){
$results[] = $array;
}
foreach ($array as $subarray){
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
HERE IS AN EXAMPLE TO BETTER ILLUSTRATE WHAT I MEAN:
Here is an example of an array I'd like to search:
Array
(
[categories] => Array
(
[1] => Array
(
[data] =>
[id] => d
[name] => Bracelets
[products] => Array
(
[0] => Array
(
[id] => j
[name] => Red
[data] =>
)
[1] => Array
(
[id] => gi
[name] => Torqoise
[data] =>
)
)
)
If I search for something with the 'id' of "j", I would get this array as the result:
Array
(
[0] => Array
(
[id] => j
[name] => Red
[data] =>
)
)
Now, ideally I would also like to know the parent key of this Array, which in the example is 'Products', which I obviously would need to retrieve before returning the results...
No, there is no built in function. You can pass parent key in the function params
You could use array_flip() to swap the key and values so you can retrieve the key with the value.
You could also slightly modify your foreach to something like
foreach ($array as $subarray_key => $subarray){
$results = array_merge($results, search($subarray, $key, $value));
}
and $subarray_key would be the key.

Categories