This question already has answers here:
Array merge on key of two associative arrays in php?
(2 answers)
Closed 9 months ago.
I have two arrays that need to be merged. I can loop through each array and merge manually. But, Is there a built in function to do this?
Array 1:
Array
(
[0] => Array
(
[detail_image_id] => 6389
[product_name] => Starter broadband Package
)
[1] => Array
(
[detail_image_id] => 6358
[product_name] => Starter broadband Package
)
)
Array 2:
Array
(
[0] => Array
(
[detail_image_id] => 6358
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-wingle.jpg
)
[1] => Array
(
[detail_image_id] => 6389
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-charji.jpg
)
)
Expected Output array is:
Array
(
[0] => Array
(
[detail_image_id] => 6389
[product_name] => Starter broadband Package
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-charji.jpg
)
[1] => Array
(
[detail_image_id] => 6358
[product_name] => Starter broadband Package
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-wingle.jpg
)
)
I have added only a sample from the array. Array is huge. Is there any PHP functions like array_merge() or array_map() that we can use instead of manual for loops and iterators?
Older & wiser: I've scrubbed my answer from years earlier because I no longer recommend the techniques. It will be most succinct and efficient to merge the arrays, feed them to a foreach() loop, then "unite" (+ is used as an array union operator) data in related rows.
The null coalescing operator (??) is used to ensure that there is always something to "unite" with.
Code: (Demo)
$result = [];
foreach (array_merge($array1, $array2) as $row) {
$result[$row['detail_image_id']] = ($result[$row['detail_image_id']] ?? []) + $row;
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'detail_image_id' => '6389',
'product_name' => 'Starter broadband Package',
'guid' => 'http://xxx/wp-content/uploads/2018/04/broadband-4mbs-charji.jpg',
),
1 =>
array (
'detail_image_id' => '6358',
'product_name' => 'Starter broadband Package',
'guid' => 'http://xxx/wp-content/uploads/2018/04/broadband-4mbs-wingle.jpg',
),
)
You can do something like:
$arr1 = array(); //Your array 1
$arr2 = array(); //Your array 2
//Make a temp array to that use detail_image_id as the key
$arr1Temp = array_combine( array_column($arr1,'detail_image_id'), $arr1 );
$arr2Temp = array_combine( array_column($arr2,'detail_image_id'), $arr2 );
//Get All unique detail_image_id from 2 arrays.
//This is to make sure that all detail_image_id's will be included.
//detail_image_id on 2nd array might not be present on the 1st one
$imgIds = array_unique(array_merge( array_keys($arr1Temp), array_keys($arr2Temp) ));
//Do a simple foreach loop
$result = array();
foreach( $imgIds as $val ) {
$result[] = array_merge( $arr1Temp[$val], $arr2Temp[$val] );
}
print_r( $result );
This will result to:
Array
(
[0] => Array
(
[detail_image_id] => 6389
[product_name] => Starter broadband Package
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-charji.jpg
)
[1] => Array
(
[detail_image_id] => 6358
[product_name] => Starter broadband Package
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-wingle.jpg
)
)
You can use a combination of array_column() and array_combine() to create a reference array using the detail_image_id as key. Then, with a foreach() loop, you can merge arrays using + operator:
$array1 = [
['detail_image_id' => '6389', 'product_name' => 'Starter broadband Package'],
['detail_image_id' => '6358', 'product_name' => 'Starter broadband Package']
];
$array2 = [
['detail_image_id' => '6358', 'guid' => 'http://xxx/wp-content/uploads/2018/04/broadband-4mbs-wingle.jpg'],
['detail_image_id' => '6389', 'guid' => 'http://xxx/wp-content/uploads/2018/04/broadband-4mbs-charji.jpg']
];
// create associative array with detail_image_id as key,
$out = array_combine(array_column($array1, 'detail_image_id'), $array1);
foreach ($array2 as $item) {
$key = $item['detail_image_id']; // shortcut for the key,
$out[$key] = $out[$key] + $item; // merge arrays
}
print_r(array_values($out)); // reset to indexed keys (0,1,2...)
Output:
Array
(
[0] => Array
(
[detail_image_id] => 6389
[product_name] => Starter broadband Package
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-charji.jpg
)
[1] => Array
(
[detail_image_id] => 6358
[product_name] => Starter broadband Package
[guid] => http://xxx/wp-content/uploads/2018/04/broadband-4mbs-wingle.jpg
)
)
Related
I have 2 arrays as below. I want to remove data from array2 if array1 has the stu_id. final array should be like result_array.
$array1 = Array
(
[0] => Array
(
[stu_id] => 1
[name] => mr.a
)
[1] => Array
(
[stu_id] => 3
[name] => mr.b
)
)
$array2 = Array
(
[0] => Array
(
[id] => 1
[stu_id] => 1
[data] => abc
)
[1] => Array
(
[id] => 2
[stu_id] => 2
[data] => xyz
)
[3] => Array
(
[id] => 3
[stu_id] => 3
[data] => aaa
)
)
$result_array = Array
(
[0] => Array
(
[id] => 2
[stu_id] => 2
[data] => xyz
)
)
I tried array_diff, $result_array = array_diff($array2, $array1); but it's not working.
Please help me to do this.
Temporarily assign keys using array_column() with stud_id (NULL retains the full subarray data), then use array_diff_key() to filter, and array_values() to reset the keys:
Code: (Demo)
$array1=[
['stu_id'=>1,'name'=>'mr.a'],
['stu_id'=>3,'name'=>'mr.b']
];
$array2=[
['id'=>1,'stu_id'=>1,'data'=>'abc'],
['id'=>2,'stu_id'=>2,'data'=>'xyz'],
['id'=>3,'stu_id'=>3,'data'=>'aaa']
];
//var_export(array_column($array1,NULL,'stu_id'));
//var_export(array_column($array2,NULL,'stu_id'));
var_export(array_values(array_diff_key(array_column($array2,NULL,'stu_id'),array_column($array1,NULL,'stu_id'))));
Output:
array (
0 =>
array (
'id' => 2,
'stu_id' => 2,
'data' => 'xyz',
),
)
If you'd like to use a foreach loop structure, generate a filtering array of stu_id's from $array1 and write a conditional check on each iteration of $array2. This method doesn't not modify the original arrays, so they can be reused "down script".
Code:
$stu_ids=array_column($array1,'stu_id');
foreach($array2 as $row){
if(!in_array($row['stu_id'],$stu_ids)){
$result[]=$row; // auto-index the qualifying subarrays
}
}
var_export($result);
// same result as above method
foreach($array1 as $data1){
foreach($array2 as $k => $data2){
if($data2["stu_id"] == $data1["stu_id"]){
unset($array2[$k]);
break;
}
}
}
$result_array = $array2;
I have an multidimensional array some values are duplicate and some unique.
duplicate values are parent and unique values are child of duplicate values.
Multidimensional array :
Array
(
[0] => Array
(
[L1_ID] => 21
[L1_ATTR_DESC] => Project Overview
[L2_ATTR_DESC] => Project Status
[L3_ATTR_DESC] => Ready
)
[1] => Array
(
[L1_ID] => 21
[L1_ATTR_DESC] => Project Overview
[L2_ATTR_DESC] => Project Status
[L3_ATTR_DESC] => Pending
)
[2] => Array
(
[L1_ID] => 21
[L1_ATTR_DESC] => Project Overview
[L2_ATTR_DESC] => Project Status
[L3_ATTR_DESC] => Completed
)
[3] => Array
(
[L1_ID] => 21
[L1_ATTR_DESC] => Project Overview
[L2_ATTR_DESC] => Project Quality
[L3_ATTR_DESC] => Independ
)
[4] => Array
(
[L1_ID] => 21
[L1_ATTR_DESC] => Project Overview
[L2_ATTR_DESC] => Project Quality
[L3_ATTR_DESC] => G+1
)
)
I want to show duplicate value print one time and unique value should be child of duplicate values.
Expected Output - Like this :
-Project Status -Project Build
--Ready --Independ
--Pending --G+1
--Completed
Just for check see whats happen: Online Link
$ps = array();
foreach($arr as $value){
$index = str_replace(" ", "", strtolower($value['L2_ATTR_DESC']));
$ps[$index][] = $value['L3_ATTR_DESC'];
}
echo '<pre>';
print_r($ps);
From now you can design it in your way.
I think what you want is commonly called "index array". You can check array_column, which I think will fill your need.
$array = array(/* multidimensional array */);
$index = array_column($array, L3_ATTR_DESC);
$index will contain an array of values associated with L3_ATTR_DESC in $array.
Working demo. You can use foreach Statement
foreach($a as $arg) {
$tmp[$arg['L1_ATTR_DESC']][$arg['L2_ATTR_DESC']][] = $arg['L3_ATTR_DESC'];
}
$output = array();
foreach($tmp as $type => $labels) {
$output[] = array(
'L1_ATTR_DESC' => $type,
'L2_ATTR_DESC' => $labels
);
}
I think you expecting output like these
Array
(
[L1_ATTR_DESC] => Project Overview
[L2_ATTR_DESC] => Array
(
[Project Status] => Array
(
[0] => Ready
[1] => Pending
[2] => Completed
)
[Project Quality] => Array
(
[0] => Independ
[1] => G+1
)
)
)
OR
foreach($a as $arg)
{
$tmp[$arg['L2_ATTR_DESC']][] = $arg['L3_ATTR_DESC'];
}
print_r($tmp);
Output
Array
(
[Project Status] => Array
(
[0] => Ready
[1] => Pending
[2] => Completed
)
[Project Quality] => Array
(
[0] => Independ
[1] => G+1
)
)
This question already has answers here:
Merge row data from multiple arrays
(6 answers)
Closed 5 months ago.
Having some difficulty trying to merge two arrays with the same numeric key. I have tried array_merge() and array_merge_recursive(), but all that seems to do is append the second array.
The first array has the following form:
Array
(
[384] => Array
(
[name] => SomeMovieName1
[age] => 12.2 hrs
[IMDBLink] =>
[IMDBRating] =>
[coverArt] =>
)
[452] => Array
(
[name] => SomeMovieName2
[age] => 13.1 hrs
[IMDBLink] =>
[IMDBRating] =>
[coverArt] =>
)
[945] => Array
(
[name] => SomeMovieName3
[age] => 13.6 hrs
[IMDBLink] =>
[IMDBRating] =>
[coverArt] =>
)
)
And here is the second array I want to combine/merge with the first:
Array
(
[384] => Array
(
[IMDBRating] => 7.2
[IMDBLink] => http://www.imdb.com/LinkToMovie1
[coverArt] => http://www.SomeLinkToCoverArt.com/1
)
[452] => Array
(
[IMDBRating] => 8.2
[IMDBLink] => http://www.imdb.com/LinkToMovie2
[coverArt] => http://www.SomeLinkToCoverArt.com/2
)
[945] => Array
(
[IMDBRating] => 6.2
[IMDBLink] => http://www.imdb.com/LinkToMovie3
[coverArt] => http://www.SomeLinkToCoverArt.com/3
)
)
And after merging, I would like the result to be:
Array
(
[0] => Array
(
[name] => SomeMovieName1
[age] => 12.2 hrs
[IMDBRating] => 7.2
[IMDBLink] => http://www.imdb.com/LinkToMovie1
[coverArt] => http://www.SomeLinkToCoverArt.com/1
)
[1] => Array
(
[name] => SomeMovieName2
[age] => 13.1 hrs
[IMDBRating] => 8.2
[IMDBLink] => http://www.imdb.com/LinkToMovie2
[coverArt] => http://www.SomeLinkToCoverArt.com/2
)
[2] => Array
(
[name] => SomeMovieName3
[age] => 13.6 hrs
[IMDBRating] => 6.2
[IMDBLink] => http://www.imdb.com/LinkToMovie3
[coverArt] => http://www.SomeLinkToCoverArt.com/3
)
)
Not sure if it's because of the inner arrays causing an issue that it won't work directly with array_merge() or array_merge_recursive(). Any help would be appreciated,
Thanks.
You can try below code to merge array. Code generates desired output required to you. I have used sample array as given by you:
<?php
$arr1=array(
"384"=>array("name"=>"SomeMovieName1","age"=>"12.2 hrs","IMDBLink"=>"","IMDBRating"=>"", "coverArt"=>""),
"452"=>array("name"=>"SomeMovieName2","age"=>"15.2 hrs","IMDBLink"=>"","IMDBRating"=>"", "coverArt"=>""),
"954"=>array("name"=>"SomeMovieName3","age"=>"4.2 hrs","IMDBLink"=>"","IMDBRating"=>"", "coverArt"=>"")
);
$arr2=array(
"384" => array("IMDBLink" => "7.2", "IMDBRating" => "http://www.imdb.com/LinkToMovie1", "coverArt" => "http://www.SomeLinkToCoverArt.com/1"),
"452" => array("IMDBLink" => "5","IMDBRating" => "http://www.imdb.com/LinkToMovie2", "coverArt" => "http://www.SomeLinkToCoverArt.com/2"),
"954"=>array("IMDBLink" => "8","IMDBRating" => "http://www.imdb.com/LinkToMovie3", "coverArt" => "http://www.SomeLinkToCoverArt.com/3")
);
$arr3 = array();
foreach($arr1 as $key=>$val)
{
$arr3[] = array_merge($val, $arr2[$key]);
}
echo "<pre>";
print_r($arr3);
?>
array_merge_recursive doesn't work because your outer array has numeric keys, not string keys. When array_merge or array_merge_recursive are given numeric arrays, they append them rather than merging elements with the same keys.
Instead, you can map through the arrays and merge the corresponding elements.
$result = array_map('array_merge', $array1, $array2);
Note that this code assumes that the two input arrays have all the same keys in the same order. If they're not in the same order, you can use ksort on them first to rearrange them.
If they can have different keys, though, you need a different solution, like the loop in Webang's answer.
It might be easier to run your arrays in a foreach loop and just insert each value into your initial array. Lets call the first array $myFirstArray and the second array $mySecondArray:
foreach ($myFirstArray as $key => $value)
{
$myFirstArray[$key][IMDBRating] = $mySecondArray[$key][IMDBRating];
$myFirstArray[$key][IMDBLink] = $mySecondArray[$key][IMDBLink];
$myFirstArray[$key][coverArt] = $mySecondArray[$key][coverArt];
}
Didn't test this, but it should work:
Call your first array $ar1, and second $ar2
$result=array();
foreach($ar1 as $k=>$v)
{
//if there is a corresponding array2 element
if( isset($ar2[$k]) ){
$result[] = array( $v['name], $v['age'], $ar2[$k]['IMDBLink'], $ar2[$k]['IMDBRating'],$ar2['coverArt']);
}
}
//result
print_r($result);
This question already has answers here:
How to group subarrays by a column value?
(20 answers)
Closed 5 months ago.
I have this result from a foreach loop.
I tried looping through the array using foreach from the answers in StackOverflow, but I'm having trouble when doing it under another foreach loop.
Array
(
[0] => Array
(
[referenceUid] => FF875951-87CB-942F-84A2-46C620BF07C8
[itemUid] => 4CD23391-AD8C-C2FB-EF4A-46093D8A37AE
[total] => 300.00
)
)
Array
(
[0] => Array
(
[referenceUid] => D267A795-E142-C25B-E042-D8A519B57DF4
[itemUid] => 4CD23391-AD8C-C2FB-EF4A-46093D8A37AE
[total] => 150.00
)
)
Array
(
[0] => Array
(
[referenceUid] => D267A795-E142-C25B-E042-D8A519B57DF4
[itemUid] => 4CD23391-AD8C-C2FB-EF4A-46093D8A37AE
[total] => 150.00
)
)
What I want is to merge the array with duplicate values on referenceUid column. Something like this:
Array
(
[0] => Array
(
[referenceUid] => FF875951-87CB-942F-84A2-46C620BF07C8
[itemUid] => 4CD23391-AD8C-C2FB-EF4A-46093D8A37AE
[total] => 300.00
)
)
Array
(
[0] => Array
(
[referenceUid] => D267A795-E142-C25B-E042-D8A519B57DF4
[itemUid] => 4CD23391-AD8C-C2FB-EF4A-46093D8A37AE
[total] => 150.00
)
[1] => Array
(
[referenceUid] => D267A795-E142-C25B-E042-D8A519B57DF4
[itemUid] => 4CD23391-AD8C-C2FB-EF4A-46093D8A37AE
[total] => 150.00
)
)
You can construct a new (merged) array and loop your input to assemble the new structure.
An important consideration is to use the common key (referenceUid) as the array key in your new array so you can reference it easily. If you don't want it at the end, simply reset the array keys e.g. $out = array_values($out).
Here's an example:
$output = array();
foreach ($input as $values) {
$key = $values['referenceUid'];
$output[$key][] = $values;
}
// Don't want the referenceUid in the keys? Reset them:
$output = array_values($output);
Example
//both arrays will be merged including duplicates
$result = array_merge( $array1, $array2 );
//duplicate objects will be removed
$result = array_map("unserialize", array_unique(array_map("serialize", $result)));
//array is sorted on the bases of id
sort( $result );`
i want to take an array and cut some of the keys from it (not in order) and create a new array from them.
I have doing it using the array_shift() function, but came to a point where the next key needed to be skipped and then do the array_shift again.
How can I logically tackle this?
my array
Array
(
[api] => Array
(
[0] => system
[1] => assets
[2] => theme
[3] => resources
[4] => api
[5] => xml
[6] => json
[7] => jsonp
[8] => request
)
[class] => Array
(
[name] => authentication
[abbr] => auth
)
[directories] => Array
(
[application] => application
[mvc] => Array
(
[model] => model
[view] => view
[controller] => controller
)
[assets] => Array
(
[folder] => assets
[css] => css
[img] => img
[js] => js
)
[config] => config
)
[smarty] => Array
(
[security] => on
[delimiter] => Array
(
[left] => {!
[right] => !}
)
[template] => Array
(
[header] => header
[footer] => footer
[extension] => tpl
)
)
[version] => Array
(
[component] => Array
(
[0] => Array
(
[name] => CMS
[version] => 1.0
)
[1] => Array
(
[name] => TinyMCE jQuery Package
[version] => 3.5
)
[2] => Array
(
[name] => jQuery
[version] => 1.7.2
)
)
)
)
I need to make a new array from they keys: api, class, version
Create an explicit list of keys that you'd like to move from one array to another. Cycle over that list, pulling from one and adding to another. Then remove the old copy from the original array:
// Original Array, and empty Array
$array = array( 'api' => 1, 'class' => 2, 'fizz' => 3, 'buzz' => 4 );
$newAr = array();
// For each key we'd like to keep
foreach ( array( 'api', 'class' ) as $key ) {
// (Re)move the value from the original array to our new array
$newAr[$key] = $array[$key]; unset( $array[$key] );
}
// Show the contents of the new array
print_r( $newAr );
Try it online now: http://codepad.org/7iYG4iVB
If it's just those 3 keys you need:
$newArray = array(
"api" => $oldArray["api"],
"class" => $oldArray["class"],
"version" => $oldArray["version"]
);
There's array_slice() which lets you 'slice' out a portion of an array. That portion can be a single element, or a range of elements. Basically the slice function lets you hack 'n chop on an array like substr() lets you hack 'n chop up a string.
This seems too simple:
$new_array = array(
'api' => $old_array['api'],
'class' => $old_array['class'],
'version' => $old_array['version']
);
Then do a var_dump( $new_array); to see if it contains the desired output.
$keys = array(1, 5, 'foo');
$new = array();
foreach ($keys as $key) {
$new[$key] = $old[$key];
// or maybe just $new[] = $old[$key];
unset($old[$key]);
}
There's shorter ways to do this, but I think you can understand how this works.
edit - Here's a shorter way
$keys = array(1, 5);
$new = array_intersect_key($old, array_flip($keys)));
$old = array_diff_key($old, array_flip($keys)));