How to merge array using UUID value - php

I have the following code :
<?php
$arr1 = array();
$arr1[] = ['UUID' => '123a-123a', 'name' => 'A1'];
$arr1[] = ['UUID' => '123b-123b', 'name' => 'B1'];
$arr1[] = ['UUID' => '123c-123c', 'name' => 'C1'];
$arr2 = array();
$arr2[] = ['UUID' => '123a-123a', 'name' => 'A2'];
$arr2[] = ['UUID' => '123b-123b', 'name' => 'B2'];
$arr2[] = ['UUID' => '123c-123c', 'name' => 'C2'];
$new_arr1 = array();
foreach ($arr1 as $key => $value) {
if(isset($new_arr1[$value['UUID']])){
$new_arr1[$value['UUID']] += ['name_a' => $value['name']];
}else{
$new_arr1[$value['UUID']] = ['name_a' => $value['name']];
}
}
$new_arr2 = array();
foreach ($arr2 as $key => $value) {
if(isset($new_arr2[$value['UUID']])){
$new_arr2[$value['UUID']] += ['name_1' => $value['name']];
}else{
$new_arr2[$value['UUID']] = ['name_2' => $value['name']];
}
}
$final_array = array_combine($new_arr1, $new_arr2);
var_dump($final_array);
Which give me the following error :
Warning: Array to string conversion in /home/user/scripts/code.php on line 32
Snippet :
https://sandbox.onlinephpfunctions.com/c/cf5fd
I want to use the UUID as an array id.
here is the expected output :
Array
(
[123a-123a] => Array
(
[name_1] => A1
[name_2] => A2
)
[123b-123b] => Array
(
[name_1] => B1
[name_2] => B2
)
[123c-123c] => Array
(
[name_1] => C1
[name_2] => C2
)
)

Instead of use array_combine you need to use array_merge_recursive because is multidimensional
Snippet:
https://sandbox.onlinephpfunctions.com/c/eae35
Reference:
array_merge_recursive

No array_combine nor intermediate arrays needed, just construct new array from those you already have:
$arr1 = array();
$arr1[] = ['UUID' => '123a-123a', 'name' => 'A1'];
$arr1[] = ['UUID' => '123b-123b', 'name' => 'B1'];
$arr1[] = ['UUID' => '123c-123c', 'name' => 'C1'];
$arr2 = array();
$arr2[] = ['UUID' => '123a-123a', 'name' => 'A2'];
$arr2[] = ['UUID' => '123b-123b', 'name' => 'B2'];
$arr2[] = ['UUID' => '123c-123c', 'name' => 'C2'];
$final_array = [];
foreach( array_merge($arr1, $arr2) as $entry ){
if( empty( $final_array[$entry['UUID']] ) )
$final_array[$entry['UUID']] = ['name_1' => $entry['name']];
else
$final_array[$entry['UUID']][ 'name_' . (count( $final_array[$entry['UUID']] ) + 1) ] = $entry['name'];
}
print_r($final_array);

array_combine creates an array by using one array for keys and another for its values. In your case, each of the 2 arrays have individual subarrays in them. Hence the error when it tries to make one of the subarrays as a string(which it can't).
In your code, you can use a single $new_arr and the make the code more concise with the null coalescing operator(??) like below:
<?php
$new_arr = array();
foreach (array_merge($arr1,$arr2) as $key => $value) {
$new_arr[$value['UUID']] = $new_arr[$value['UUID']] ?? [];
$new_arr[$value['UUID']] += [('name_' . (count($new_arr[$value['UUID']]) + 1)) => $value['name']];
}
print_r($new_arr);
Online Demo

Related

Group 2d array by column value and concatenate values within each group

I have a simple php array for location postcode and their name. I want compress 'code' by 'name'. This code from WooCommerce database zones.
$new_arr = [
[
'name' => 'Jambi Selatan',
'code' => '36139',
'code_name' => '36139 - Jambi Selatan'
],
[
'name' => 'Jambi Selatan',
'code' => '36137',
'code_name' => '36137 - Jambi Selatan'
],
[
'name' => 'Bagan Pete',
'code' => '36129',
'code_name' => '36129 - Bagan Pete'
],
[
'name' => 'Bagan Pete',
'code' => '36127',
'code_name' => '36127 - Bagan Pete'
]
];
I want get final result combined by 'name' and 'code' like this: i try array_unique method but not working.
Array (
[0] => Array
(
[name] => Jambi Selatan
[code] => 36139, 36137
[code_name] => 36139, 36139 - Jambi Selatan
)
[1] => Array
(
[name] => Bagan Pete
[code] => 36127, 36129
[code_name] => 36127, 36129 - Bagan Pete
)
)
I try this method, but not fix at 'code_name'
$out = array();
foreach ($new_arr as $key => $value){
if (array_key_exists($value['name'], $out)){
$out[$value['name']]['code'] .= ', '.$value['code'];
} else {
$out[$value['name']] = array(
'name' => $value['name'],
'code' => $value['code'],
'code_name' => $value['code'] . ' - ' . $value['name']
);
}
}
$out = array_values($out);
print_r($out);
You have to check duplicate name by in_array and update exist array value .If not exist insert that value to $out array .
$out = array();
foreach($new_arr as $k=>$v) {
//empty array state
if(count($out) == 0) {
$out[] = $v;
continue;
}
foreach ($out as $key => $value) {
if(in_array($v["name"],$value)) {
$out[$key]["code"] .= ",".$v["code"];
//for the code_name output as OP described
$nn = explode("-", $value["code_name"]);
$l = count($nn) - 1;
unset($nn[$l]);
$out[$key]["code_name"] = implode($nn).",".$v["code_name"];
break;
} else {
if((count($out)-1) == $key) {
$out[] = $v;
}
}
}
}
var_dump($out);
For someone have problem like me, this method for fix it:
$out = array();
foreach ($new_arr as $key => $value){
if (array_key_exists($value['name'], $out)){
$out[$value['name']]['code'] .= ', '.$value['code'];
$out[$value['name']]['code_name'] .= ', '.$value['code'] . ' - ' . $value['name'];
} else {
$out[$value['name']] = array(
'name' => $value['name'],
'code' => $value['code'],
'code_name' => $value['code']
);
}
}
$out = array_values($out);
print_r($out);
Final result;
Array
(
[0] => Array
(
[name] => Jambi Selatan
[code] => 36139, 36137
[code_name] => 36139, 36137 - Jambi Selatan
)
[1] => Array
(
[name] => Bagan Pete
[code] => 36129, 36127
[code_name] => 36129, 36127 - Bagan Pete
)
)
Please try below one as another approach:
<?php
$arr = Array (
Array
(
'name' => 'Jambi Selatan',
'code' => '36139',
'code_name' => '36139 - Jambi Selatan'
),
Array
(
'name' => 'Jambi Selatan',
'code' => '36137',
'code_name' => '36137 - Jambi Selatan'
),
Array
(
'name' => 'Bagan Pete',
'code' => '36129',
'code_name' => '36129 - Bagan Pete'
),
Array
(
'name' => 'Bagan Pete',
'code' => '36127',
'code_name' => '36127 - Bagan Pete'
)
);
$newarr = array();
$finalArr = array();
foreach($arr as $aa) {
$newarr[$aa['name']][] = $aa;
}
foreach($newarr as $kk => $bb) {
foreach($bb as $cc) {
$finalArr[$kk]['name'] = $cc['name'];
if(isset($finalArr[$kk]['code'])) {
$finalArr[$kk]['code'] = $finalArr[$kk]['code'].','.$cc['code'];
} else {
$finalArr[$kk]['code'] = $cc['code'];
}
if(isset($finalArr[$kk]['code_name'])) {
$finalArr[$kk]['code_name'] = $finalArr[$kk]['code_name'].','.$cc['code_name'];
} else {
$finalArr[$kk]['code_name'] = $cc['code_name'];
}
}
}
echo "<pre>";
print_r($finalArr);
echo "</pre>";
?>
Definitely avoid any suggestions that use more than one loop to group and concatenate the data.
I do endorse #Opsional's snippet. An alternative approach is to push reference variables into the result array, then only concatenate comma-separated values to the appropriate reference variable.
Code: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($ref[$row['name']])) {
$ref[$row['name']] = $row;
$result[] = &$ref[$row['name']];
} else {
$ref[$row['name']]['code'] .= ', ' . $row['code'];
$ref[$row['name']]['code_name'] .= ', ' . $row['code_name'];
}
}
var_export($result);
For any purist developers that insist on destroying references, call unset($ref) after the loop.
Here is a streamlined version of #Opsional's snippet: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($result[$row['name']])) {
$result[$row['name']] = $row;
} else {
$result[$row['name']]['code'] .= ', ' . $row['code'];
$result[$row['name']]['code_name'] .= ', ' . $row['code_name'];
}
}
var_export(array_values($result));

PHP: Link address of multiple array keys into another bigger array

I want to combine 3 small arrays that have unique keys between them into 1 big array but when I modify a value in the big array I want it also to reflect in the corresponding small array.
For example I have these 3 small arrays:
$arr1 = ['key1' => 'data1', 'key2' => 'data2'];
$arr2 = ['key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5'];
$arr3 = ['key6' => 'data6'];
I want to have a $bigArray that has each key's address linked/mapped to each value of the small arrays. So if I do something like:
$bigArray['key4'] = 'something else';
then it would modify $arr2['key4'] to the same value ('something else').
If I try something like:
$bigArray = [&$arr1, &$arr2, &$arr3];
It has the unfortunate effect of making a multidimensional array with the keys to the values mapped.
Two ways i found
<?php
error_reporting(E_ALL);
$arr1 = ['key1' => 'data1', 'key2' => 'data2'];
$arr2 = ['key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5'];
$arr3 = ['key6' => 'data6'];
$big = [];
if (true) {
foreach (['arr1', 'arr2', 'arr3'] as $v) {
foreach (array_keys($$v) as $k) {
$big[$k] = &${$v}[$k];
}
}
}
else {
foreach ([&$arr1, &$arr2, &$arr3] as &$v) {
foreach (array_keys($v) as $k) {
$big[$k] = &$v[$k];
}
}
}
$big['key1'] = 'data1mod';
print_r($big);
print_r($arr1);
3rd way with function
$big = [];
$bindToBig = function (&$a) use (&$big) {
foreach (array_keys($a) as $k) {
$big[$k] = &$a[$k];
}
};
$bindToBig($arr1);
$bindToBig($arr2);
$bindToBig($arr3);
You can't bind data that way, but you can link them in the same object:
class ArrayLink {
public $bigArray;
public $linkedChildrenArray;
protected $childrenArray;
public function __construct( $childrenArray ) {
$this->childrenArray = $childrenArray;
}
public function changeValueForKey( $arrKey, $arrValue ) {
foreach ( $this->childrenArray as $key => $value ) {
foreach ( $value as $subKey => $subValue ) {
if ( $arrKey == $subKey ) {
$this->bigArray[ $subKey ] = $arrValue;
$this->childrenArray[ $key ][ $subKey ] = $arrValue;
}
}
}
$this->linkedChildrenArray = (object) $this->childrenArray;
}
}
As you can see, the $arr2 now need to be access from $arrayLink object:
$arr1 = [ 'key1' => 'data1', 'key2' => 'data2' ];
$arr2 = [ 'key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5' ];
$arr3 = [ 'key6' => 'data6' ];
$arrayLink = new ArrayLink( array( 'arr1' => $arr1, 'arr2' => $arr2, 'arr3' => $arr3 ) );
$arrayLink->changeValueForKey( 'key3', 'new value for key 3' );
echo $arrayLink->bigArray['key3']; //new value for key 3
echo $arrayLink->linkedChildrenArray->arr2['key3']; //new value for key 3

How do I reform this array into a differently structured array

I have an array that looks like this:
[0] => Array
(
[name] => typeOfMusic
[value] => this_music_choice
)
[1] => Array
(
[name] => myMusicChoice
[value] => 9
)
[2] => Array
(
[name] => myMusicChoice
[value] => 8
)
I would like to reform this into something with roughly the following structure:
Array(
"typeOfMusic" => "this_music_choice",
"myMusicChoice" => array(9, 8)
)
I have written the following but it doesn't work:
foreach($originalArray as $key => $value) {
if( !empty($return[$value["name"]]) ){
$return[$value["name"]][] = $value["value"];
} else {
$return[$value["name"]] = $value["value"];
}
}
return $return;
I've tried lots of different combinations to try and get this working. My original array could contain several sets of keys that need converting to arrays (i.e. it's not always going to be just "myMusicChoice" that needs converting to an array) ?
I'm getting nowhere with this and would appreciate a little help. Many thanks.
You just need to loop over the data and create a new array with the name/value. If you see a repeat name, then change the value into an array.
Something like this:
$return = array();
foreach($originalArray as $data){
if(!isset($return[$data['name']])){
// This is the first time we've seen this name,
// it's not in $return, so let's add it
$return[$data['name']] = $data['value'];
}
elseif(!is_array($return[$data['name']])){
// We've seen this key before, but it's not already an array
// let's convert it to an array
$return[$data['name']] = array($return[$data['name']], $data['value']);
}
else{
// We've seen this key before, so let's just add to the array
$return[$data['name']][] = $data['value'];
}
}
DEMO: https://eval.in/173852
Here's a clean solution, which uses array_reduce
$a = [
[
'name' => 'typeOfMusic',
'value' => 'this_music_choice'
],
[
'name' => 'myMusicChoice',
'value' => 9
],
[
'name' => 'myMusicChoice',
'value' => 8
]
];
$r = array_reduce($a, function(&$array, $item){
// Has this key been initialized yet?
if (empty($array[$item['name']])) {
$array[$item['name']] = [];
}
$array[$item['name']][] = $item['value'];
return $array;
}, []);
$arr = array(
0 => array(
'name' => 'typeOfMusic',
'value' => 'this_music_choice'
),
1 => array(
'name' => 'myMusicChoice',
'value' => 9
),
2 => array(
'name' => 'myMusicChoice',
'value' => 8
)
);
$newArr = array();
$name = 'name';
$value = 'value';
$x = 0;
foreach($arr as $row) {
if ($x == 0) {
$newArr[$row[$$name]] = $row[$$value];
} else {
if (! is_array($newArr[$row[$$name]])) {
$newArr[$row[$$name]] = array();
}
array_push($newArr[$row[$$name]], $row[$$value]);
}
$x++;
}

merge two associative arrays add titles

I have two arrays
$Array_1 = array(
'ID_1' => 'Michael',
'ID_2' => 'Jerry',
'ID_3' => 'Tony',
'ID_4' => 'Roger',
);
$Array_2 = array(
'ID_1' => 'Chef',
'ID_2' => 'Mechanic',
'ID_3' => 'Cook',
'ID_4' => 'Dealer',
);
I wish to merge them on the ID column and have my final array be in this form
$employees = array(
array(
'name' => 'Jason',
'occupation' => 'Chef'
),
array(
'name' => 'Mike',
'occupation' => 'Mechanic'
),
...
);
I know I can array combine them like below:
$new_array = array_combine(array_values($Array_1), array_values($Array_2));
but how would I add the titles "Name": and "Occupation":
Can you try this,
$Employees = array();
foreach($Array_1 as $key=>$value):
$Employees['Employees'][] = array('Name'=>$value, 'Occupation'=>$Array_2[$key]);
endforeach;
echo "<pre>";
print_r($Employees);
echo "</pre>";
echo json_encode($Employees);
OP:
{"Employees":[{"Name":"Jason","Occupation":"Chef"}, {"Name":"Mike","Occupation":"Mechanic"}]}
i dont know how the array look. but you can try my two solution
First solution
$array1 = array("id" => array("id1", "id2", "id3"), "names" => array("name1", "name2", "name3"));
$array2 = array("id" => array("id1", "id2", "id3"), "occupation" => array("occupation1", "occupation2", "occupation3"));
$filter_array = array("employees" => array());
foreach ($array1["id"] as $index => $key) {
$employee = array();
$occupation = in_array($key, $array2["id"]) ? $array2["occupation"][$index] : false;
if ($occupation === false) {
continue;
}
$employee["name"] = $key;
$employee["occupation"] = $occupation;
array_push($filter_array["employees"], $employee);
}
echo "<pre>" . print_r($filter_array, true) . "</pre>";
Second Solution
$array1 = array("id1" => array("names" => "name1"), "id2" => array("names" => "name2"), "id3" => array("names" => "name3"));
$array2 = array("id1" => array("occupation" => "occupation1"), "id2" => array("occupation" => "occupation2"), "id3" => array("occupation" => "occupation3"));
$filter_array = array("employees" => array());
foreach ($array1 as $key => $value) {
$employee = array();
if (!isset($array2[$key])) {
continue;
}
$employee["name"] = $value["names"];
$employee["occupation"] = $array2[$key]["occupation"];
array_push($filter_array["employees"], $employee);
}
echo "<pre>" . print_r($filter_array, true) . "</pre>";
i hope my code can help.
you can try this
$Array_1 = array(
'ID_1' => 'Michael',
'ID_2' => 'Jerry',
'ID_3' => 'Tony',
'ID_4' => 'Roger',
);
$Array_2 = array(
'ID_1' => 'Chef',
'ID_2' => 'Mechanic',
'ID_3' => 'Cook',
'ID_4' => 'Dealer',
);
$filter_array = array("employees" => array());
foreach($Array_1 as $key => $value){
$employee = array();
if(!isset($Array_2[$key])){ continue; }
$employee["name"] = $value;
$employee["occupation"] = $Array_2[$key];
array_push($filter_array["employees"], $employee);
}
EDIT 2
Aah, now I see the phpfiddle in the comments and the edit to the OP. So, the ID is already the key of the array? ... Then just do
foreach($Array_1 as $key_1 => $value_1) {
$new_Array[$key_1]['Names'] = $Array_1['Names'];
}
foreach($Array_2 as $key_2 => $value_2) {
$new_Array[$key_2]['Occupation'] = $Array_2['Occupation'];
}
use array_walk . It runs a function per each array item .combine them in the function .

PHP: Merge arrays in loop

public function getCheckoutForm(){
$arr = array(
'cmd' => '_cart',
'business' => 'some#mail',
'no_shipping' => '1',
'upload' => '1',
'return' => 'url',
'cancel_return' => 'url1',
'no_note' => '1',
'currency_code' => 'url2',
'bn' => 'PP-BuyNowBF');
$cpt=1;
foreach($this->items as $item){
$arr1[] = array(
'item_number_'.$cpt.'' => $item['item_id'],
'item_name_'.$cpt.'' => $item['item_name'],
'quantity_'.$cpt.'' => $item['item_q'],
'amount_'.$cpt.'' => $item['item_price']
);
$cpt++;
}
return array_merge($arr,$arr1[0],$arr1[1]);
}
This returns array like that:
Array
(
[cmd] => _cart
[business] => some#mail
[no_shipping] => 1
[upload] => 1
[return] => url1
[cancel_return] =>url2
[no_note] => 1
[currency_code] => EUR
[bn] => PP-BuyNowBF
[item_number_1] => 28
[item_name_1] => item_name_1
[quantity_1] => 1
[amount_1] => 5
[item_number_2] => 27
[item_name_2] => item_name_2
[quantity_2] => 1
[amount_2] => 30
)
The problem is that in return $arr1[0] and $arr1[1] are hardcoded. And if in loop i have more than 2 arrays, lets say 0,1,2,3 ans so on, this code won't work. Any idea? Maybe my logic is compleatly wrong...
There's no need to create arrays in your loop - just add new keys directly to the first array:
public function getCheckoutForm(){
$arr = array(
'cmd' => '_cart',
'business' => 'some#mail',
'no_shipping' => '1',
'upload' => '1',
'return' => 'url',
'cancel_return' => 'url1',
'no_note' => '1',
'currency_code' => 'url2',
'bn' => 'PP-BuyNowBF'
);
$cpt=1;
foreach($this->items as $item){
$arr['item_number_'.$cpt] = $item['item_id'];
$arr['item_name_'.$cpt] = $item['item_name'];
$arr['quantity_'.$cpt] = $item['item_q'];
$arr['amount_'.$cpt] = $item['item_price'];
$cpt++;
}
return $arr;
}
I would probably do something like
$count = count($arr1);
for($i=0;$i<$count;$i++){
$arr = array_merge($arr,$arr1[$i]);
}
return $arr;
I hope, I understood, what you mean ^^
foreach ($i = 0, $n = count($arr1); $i < $n; $i++) {
$arr = array_merge($arr, $arr1[$i]);
}
return $arr;
You could do the merge in every iteration:
foreach($this->items as $item){
$temp_arr = array(
'item_number_'.$cpt.'' => $item['item_id'],
'item_name_'.$cpt.'' => $item['item_name'],
'quantity_'.$cpt.'' => $item['item_q'],
'amount_'.$cpt.'' => $item['item_price']
);
$arr = array_merge($arr,$temp_arr)
$cpt++;
}
which has the advantage that you could possibly get $temp_arr from a function,
or just add all the elements to one array:
foreach($this->items as $item){
$arr['item_number_'.$cpt.''] => $item['item_id'];
$arr['item_name_'.$cpt.''] => $item['item_name'];
$arr['quantity_'.$cpt.''] => $item['item_q'];
$arr['amount_'.$cpt.''] => $item['item_price'];
$cpt++;
}
do this
$count = count($data);
$sum = 1;
$arr = [];
for($i=0;$i<$count;$i++){
$temp = $arr;
if($i == $count - 1){
$sum = 0;
}
$arr = array_merge($temp,$data[$i + $sum]);
}
return $arr;

Categories