Merge two 2d arrays on shared value from different keys - php

I two arrays set out like this.
First array
Array
(
[0] => Array
(
[manufacture] => Moto
[name] => ZSX 125
[code] => ZS125-48A
[cc] => 125
[bike_type] => 3 Motorcycle
[title] => Mto ZSX 125
[about] => The ZSX
)
[1] => Array
(
[manufacture] => Moto
[name] => LSM 125
[code] => STR125YB
[cc] => 125
[bike_type] => 6 Endurancemotor
[title] => Moto
[about] => Moto
)
)
Second array
Array
(
[0] => Array
(
[id] => 183
[model] => ZS125-48A
[engine_brand] => 158FMI-B
[engine_type] => Single Cylinder
)
[1] => Array
(
[id] => 172
[model] => STR125YB
[engine_brand] => K154FMI
[engine_type] => Single Cylinder
)
)
As you can see 'code' from the first array is the same as 'model' from the second and there will always be a match.
This is the array i would like to have.
Array
(
[0] => Array
(
[id] => 183
[model] => ZS125-48A
[engine_brand] => 158FMI-B
[engine_type] => Single Cylinder
[manufacture] => Moto
[name] => ZSX 125
[code] => ZS125-48A
[cc] => 125
[bike_type] => 3 Motorcycle
[title] => Moto ZSX 125
[about] => The ZSX
)
[1] => Array
(
[id] => 172
[model] => STR125YB
[engine_brand] => K154FMI
[engine_type] => Single Cylinder
[manufacture] => Moto
[name] => LSM 125
[code] => STR125YB
[cc] => 125
[bike_type] => 6 Endurancemotor
[title] => Moto
[about] => Moto
)
)
Is this possible? i have tried array_merge and array_merge_recursive, but it only appends the second array onto the end of the first, it doesnt merge it on the keys.

Deceze's solution is perfect if the two arrays are synchronized (i.e. items with matching code and model are at the same index in both arrays). If that is not the case you will need more than one line of code.
The arrays need to have string keys in order to be merged with array_merge. In this case you want to rekey the first one based on code and the second based on model. After rekeying you can merge them with array_merge_recursive.
Rekeying is easy in PHP 5.5+:
// array_column will conveniently rekey when the second argument is null
$array1 = array_column($array1, null, 'code');
$array2 = array_column($array2, null, 'model');
A bit more complicated in earlier versions:
// array_map is a more complicated way to extract a column from an array
// and array_combine will do the rekeying
$array1 = array_combine(
array_map(function($i) { return $i['code']; }, $array1),
$array1);
$array2 = array_combine(
array_map(function($i) { return $i['model']; }, $array2),
$array2);
In both cases the final step would be the same:
$result = array_merge_recursive($array1, $array2);

Looks to me like this should do it:
$array3 = array_map('array_merge', $array1, $array2);
This feeds $array1[0] and $array2[0] to array_merge, then $array1[1] and $array2[1] etc.

And, if you prefer "simpler" code... :-)
$result = array();
foreach ($one as $a) {
foreach ($two as $b) {
if ($a->code == $b->model) {
array_push($result, array_merge($a, $b));
break;
}
}
}
print_r($result);

Related

Sort array by date

My array has an array for each field (i.e date, name, etc.). How do I sort the array by date? Should I create another array? Can I use sort or unsort here. If yes, how? Here is my array:
Array
(
[date] => Array
(
[0] => 03/11/2019
[1] => 03/19/2019
[2] => 03/15/2019
[3] => 12/15/2018
)
[name] => Array
(
[0] => Lowa
[1] => Stephanie
[2] => Allan
[3] => Joffer
)
[number] => Array
(
[0] => 178989898
[1] => 111111111
[2] => 222222222
[3] => 333333333
)
[unit] => Array
(
[0] => HR
[1] => VPP
[2] =>
[3] => OAT
)
[department] => Array
(
[0] => Chemistry
[1] => IT
[2] => Lab
[3] => Contractor
)
)
At the end, my first element will be:
03/19/2019 Stephanie 111111111 VPP IT
I think your data can be better organized:
$newArr = Array
(
[0] => Array
(
[date] => 03/11/2019
[name] => Lowa
[number] => 178989898
[unit] => HR
[department] => Chemistry
)
[1] => Array
(
[date] => 03/19/2019
[name] => Stephanie
[number] => 111111111
[unit] => VPP
[department] => IT
)
[2] => Array
(
[date] => 03/15/2019
[name] => Allan
[number] => 222222222
[unit] =>
[department] => Lab
)
[3] => Array
(
[date] => 12/15/2018
[name] => Joffer
[number] => 333333333
[unit] => OAT
[department] => Contractor
)
);
Then, you can simply sort it by:
function cmp($a, $b) {
if ($a["date"] == $b["date"]) return 0;
return ($a["date"] < $b["date"]) ? -1 : 1;
}
usort($newArr, "cmp");
Please be warned that dates in the format "Month/Day/Year" ar not alphabetically sortable.
You definitively should use a Year/Month/Day format for your dates, or write a more specific cmp() function...
UPDATE: To answer OP's question in comment: just reverse $row and 'field' order:
for ($row = 0; $row < count($date); $row++) {
$newArr[$row]['date'] = $date[$row];
$newArr[$row]['name'] = $name[$row];
...
}
First save the keys of your array - then by using array_value convert to integer keys so you can use the ... operator.
Then you can use array_filter with null function to re-organize your array. Next step will be to get the keys back using array_map and array_combine.
Last step - sort by "data" with usort
Consider the following example:
$arr = ["date" => ["3", "7", "5"], "name" => ["aa", "bb", "cc"]]; // this can have a lot more sub-array inside
$keys = array_keys($arr); // extract the keys for later use
$res = array_map(null, ...array_values($arr)); // transposed the array
$res = array_map(function ($e) use ($keys) {return array_combine($keys, $e);}, $res); // return the keys to the transposed array
usort($res, function ($a, $b) {return strcmp($a['date'], $b['date']);} ); // sort all by "date"
Reference:
array-keys, array-filter, array-map, usort, array-values
Notice #MarcoS post comment regarding the comparing dates

How to remove key from another array that holds values?

let's suppos we have the following two arrays
Let's suppose this is called $array1
Array
(
[0] => Array
(
[Name] => Jack
[Height] => 190
[Shoe Size] => 40
)
[1] => Array
(
[Name] => Rose
[Height] => 160
[Shoe Size] => 52
)
)
Suppose this is called $array2
Array
(
[0] => Name
[1] => Shoe Size
)
Now, what I need to do, is to keep the keys in $array1 which are found in $array2 as values, so the output I'm expecting is something like this
Array
(
[0] => Array
(
[Name] => Jack
[Shoe Size] => 40
)
[1] => Array
(
[Name] => Rose
[Shoe Size] => 52
)
)
I tried array_intersect and array_intersect_key but they're both failing. does anyone have any idea how to do this?
What you need is array_intersect_key with array_flip
$array3 = array_flip($array2);
foreach($array1 as &$a) {
$a = array_intersect_key($a, $array3);
}

Merging two array elements into one array element in PHP

I want to merge two arrays into one array as follows,
Array1:
Array
(
[0] => Array
(
[id] => 3
[sku] => KOG456
[cart_id] => 2
[name] => Young Money
[slug] => young-money
[route_id] => 47
[description] =>
This is test song
[excerpt] =>
[saleprice] => 90.00
[related_products] =>
[images] => {"1c6b0883fc94c5f644497ec488cdf8cb":{"filename":"1c6b0883fc94c5f644497ec488cdf8cb.jpg","alt":"Test","caption":"","primary":true}}
[seo_title] =>
[meta] =>
[enabled] => 1
)
)
Array2:
Array
(
[0] => Array
(
[filename] => Beethovens_Symphony_No._9_(Scherzo).wma
[title] => Young Money
[size] => 599.26
)
)
Expected array result is:
Array
(
[0] => Array
(
[id] => 3
[sku] => KOG456
[cart_id] => 2
[name] => Young Money
[slug] => young-money
[route_id] => 47
[description] =>
This is test song
[excerpt] =>
[saleprice] => 90.00
[related_products] =>
[images] => {"1c6b0883fc94c5f644497ec488cdf8cb":{"filename":"1c6b0883fc94c5f644497ec488cdf8cb.jpg","alt":"Test","caption":"","primary":true}}
[seo_title] =>
[meta] =>
[enabled] => 1
[filename] => Beethovens_Symphony_No._9_(Scherzo).wma
[title] => Young Money
[size] => 599.26
)
)
How to merge these array elements into one array element ?
foreach ($origArray as $key => &$subArray)
$subArray += $arrayToBeAdded[$key];
Where $origArray is your array which is to be merged into and $arrayToBeAdded the array you merge into.
User array_merge_recursive():
$final = array_merge_recursive($array1, $array2);
Try this little known overload of the + operator for arrays:
$result = $array1[0] + $array2[0]
Use function array_merge($array1[0], $array2[0]) . Following is the example for the same
$array1 = array(0=>array('1'=>1,'2'=>2,'3'=>3));
$array2 = array(0=>array('4'=>4,'5'=>5,'6'=>6));
$result[0] = array_merge($array1[0],$array2[0]);
echo '<pre>';
print_r($result);
Since you have unique keys, you could use something as simple as the + operator (union)...
For example:
$arr1 = [1=>'testing',2=>'stack',3=>'overflow'];
$arr2 = [4=>'something',5=>'else',6=>'here'];
$arr3 = $arr1 + $arr2;
print_r($arr3);
Results:
Array ( [1] => testing [2] => stack [3] => overflow [4] => something [5] => else [6] => here )
For this php has multiple functions. You can use $arrays = array_combine($array1, $array2);.
PHP.net - array_combine
Hope it helped!

merge array in single array

I have used the following code to get array and merge them.
On the print_r(arr1) I get following array. In $arr I am trying to merge array but when i print_($arr) at the end of for-each I get same array.
Am I doing wrong array merge?
How can i combine or merge it?
foreach($q1->result_array() as $row4)
{
$arr1 = $q1->result_array();
echo"<pre>";
print_r($arr1);
echo"</pre>";
$arr = array_merge($arr, $arr1);
echo "<br/>";
$id = $row4['id'];
$parent_id = $row4['parent_id'];
if(!empty($arr1))
{
$this->showreply($id);
}
}
print_r($arr);
Array which i get on print_r($arr1):
Array
(
[0] => Array
(
[id] => 69
[reply] => First reply to Reply
[parent_id] => 68
[postid] => 0
[us_id] => 41
[added_by] => Shailesh
[photo] => 9.jpg
[added_on] => 2013-04-01 16:06:13
)
)
Array
(
[0] => Array
(
[id] => 70
[reply] => Reply to Nested Reply
[parent_id] => 69
[postid] => 0
[us_id] => 41
[added_by] => Shailesh
[photo] => 9.jpg
[added_on] => 2013-04-01 16:07:24
)
)
Array
(
[0] => Array
(
[id] => 52
[reply] => Reply on demand
[parent_id] => 70
[postid] => 0
[us_id] => 50
[added_by] => swapnil
[photo] =>
[added_on] => 2013-03-29 16:27:57
)
)
$arr = array_merge($arr, $arr1);
This $arr variable was never initialized, so nothing plus $arr1 equals to $arr1.
Also why is this code inside a foreach?
try this...i think this is what you are looking for
foreach($q1->result_array() as $row4)
{
$arr1 = $q1->result_array();
$arr[]=$row4;
}
print_r($arr)

Merge two object arrays and remove duplicated objects then sort by column value

I have the following two arrays of objects:
First Array: $array1
Array
(
[0] => stdClass Object
(
[id] => 100
[name] => Muhammad
)
[1] => stdClass Object
(
[id] => 102
[name] => Ibrahim
)
[2] => stdClass Object
(
[id] => 101
[name] => Sumayyah
)
)
Second Array: $array2
Array
(
[0] => stdClass Object
(
[id] => 100
[name] => Muhammad
)
[1] => stdClass Object
(
[id] => 103
[name] => Yusuf
)
)
I want to merge these two object arrays (removing all duplicates) and sorted according to id.
Desired output:
Array
(
[0] => stdClass Object
(
[id] => 100
[name] => Muhammad
)
[1] => stdClass Object
(
[id] => 101
[name] => Sumayyah
)
[2] => stdClass Object
(
[id] => 102
[name] => Ibrahim
)
[3] => stdClass Object
(
[id] => 103
[name] => Yusuf
)
)
These 3 simple steps did the work:
//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 );
Note: Answer by #Kamran helped me come to this simple solution
UPDATE
I am posting the entire code listing here now instead of the previously posted main code, printing both input and output. You can simply copy and paste this code to test.
<?php
function array_to_object($arr) {
$arrObject = array();
foreach ($arr as $array) {
$object = new stdClass();
foreach ($array as $key => $value) {
$object->$key = $value;
}
$arrObject[] = $object;
}
return $arrObject;
}
function super_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value) {
if ( is_array($value) ) {
$result[$key] = super_unique($value);
}
}
return $result;
}
function merge_arrays($arr1, $arr2) {
$arr1 = (array)$arr1;
$arr2 = (array)$arr2;
$output = array_merge($arr1, $arr2);
sort($output);
return super_unique($output);
}
$array1 = array(
array("id" => "100", "name" => "muhammad"),
array("id" => "102", "name" => "ibrahim"),
array("id" => "101", "name" => "summayyah"),
);
$array1 = array_to_object($array1);
print "<h3>Your array 1</h3>";
print "<pre>";
print_r($array1);
print "</pre>";
$array2 = array(
array("id" => "100", "name" => "muhammad"),
array("id" => "103", "name" => "yusuf"),
);
$array2 = array_to_object($array2);
print "<h3>Your array 2</h3>";
print "<pre>";
print_r($array2);
print "</pre>";
$result = merge_arrays($array1, $array2);
print "<h3>Your desired output</h3>";
print "<pre>";
print_r($result);
print "</pre>";
it will output the following:
Your array 1
Array
(
[0] => stdClass Object
(
[id] => 100
[name] => muhammad
)
[1] => stdClass Object
(
[id] => 102
[name] => ibrahim
)
[2] => stdClass Object
(
[id] => 101
[name] => summayyah
)
)
Your array 2
Array
(
[0] => stdClass Object
(
[id] => 100
[name] => muhammad
)
[1] => stdClass Object
(
[id] => 103
[name] => yusuf
)
)
Your desired output
Array
(
[0] => stdClass Object
(
[id] => 100
[name] => muhammad
)
[2] => stdClass Object
(
[id] => 101
[name] => summayyah
)
[3] => stdClass Object
(
[id] => 102
[name] => ibrahim
)
[4] => stdClass Object
(
[id] => 103
[name] => yusuf
)
)
Assignments:
Merge
Remove Duplicates
Sort by id
The good news is: Assigning temporary keys using id values does all of the hard work for you. No serializing is needed.
array_merge() joins the arrays together.
array_column() with a null 2nd parameter leaves the objects unmodified and id as the 3rd parameter assigns the temporary keys. Because arrays cannot have duplicate keys, duplicate objects are weeded out in this step.
Now that we have keys, ksort() avoids calling the more convoluted usort() to sort by id ascending.
Finally, call array_values() to re-index the resultant array (remove the temporary keys).
Code: (Demo)
$array1 = [
(object) ['id' => 100, 'name' => 'Muhammad'],
(object) ['id' => 102, 'name' => 'Ibrahim'],
(object) ['id' => 101, 'name' => 'Sumayyah']
];
$array2 = [
(object) ['id' => 100, 'name' => 'Muhammad'],
(object) ['id' => 103, 'name' => 'Yusuf']
];
$merged_keyed = array_column(array_merge($array1,$array2), NULL, 'id');
ksort($merged_keyed);
var_export(array_values($merged_keyed));
Alternatively, you can filter one of the arrays to remove duplicates, then merge them, then sort them. sort() will effectively order the rows by the id column because the rows have equal size and id is the element in first position.
Code: (Demo)
$result = array_merge($array1, array_udiff($array2, $array1, fn($a, $b) => $a <=> $b));
sort($result);
var_export($result);

Categories