merge recursive on inner arrays of multidimensional array php - php

I have a multidimensional array that looks like such:
Array
(
[0] => Array
(
[email] => email1#gmail.com
[added] => style-narcotics
)
[1] => Array
(
[email] => email1#gmail.com
[added] => style-edm
)
[2] => Array
(
[email] => email2#gmail.com
[added] => style-codeine
)
[3] => Array
(
[email] => email2#gmail.com
[added] => style-food
)
)
I want to merge all the inner arrays combining the "added" key like such:
Array
(
[0] => Array
(
[email] => email1#gmail.com
[added] => array(
[0]=>style-narcotics
[1]=>style-edm
)
)
[1] => Array
(
[email] => email2#gmail.com
[added] => array(
[0]=>style-codeine
[1]=>style-food
)
)
I have tried merge array recursive in different forms and call_user_func but it doesnt cut it. Any advice? Thanks!

I would call it "grouping", but not "merging".
Use the following approach with array_walk and array_values functions:
$grouped = [];
// $arr is your initial array
array_walk($arr, function($v) use (&$grouped){
if (array_key_exists($v["email"], $grouped)) {
$grouped[$v["email"]]["added"][] = $v["added"];
} else {
$v["added"] = [$v["added"]];
$grouped[$v["email"]] = $v;
}
});
print_r(array_values($grouped));
The output:
Array
(
[0] => Array
(
[email] => email1#gmail.com
[added] => Array
(
[0] => style-narcotics
[1] => style-edm
)
)
[1] => Array
(
[email] => email2#gmail.com
[added] => Array
(
[0] => style-codeine
[1] => style-food
)
)
)

A simple solution that uses array_reduce():
$output = array_reduce(
$input,
function (array $carry, array $item) {
$email = $item['email'];
if (! isset($carry[$email])) {
// It's a new email, make room for it in the output
$carry[$email] = array('email' => $email, 'added' => array(), );
}
// Add the value of $item['added'] into the existing array
$carry[$email]['added'][] = $item['added'];
return $carry;
},
array()
);
// Output is indexed by email addresses. If you need numeric keys then...
$output = array_values($output);
The same logic as above but with an explicit iteration over the input array (the code is a couple of lines shorter):
$output = array();
foreach ($input as $item) {
$email = $item['email'];
if (! isset($carry[$email])) {
// It's a new email, make room for it in the output
$carry[$email] = array('email' => $email, 'added' => array(), );
}
// Add the value of $item['added'] into the existing array
$carry[$email]['added'][] = $item['added'];
}
$output = array_values($output);

Related

Sequence issue with nested foreach loop php

I have two array. array one and array two. I want to merge these array into single array with key. My output result is valid but sequence is not correct.
Array one
Array
(
[0] => test-685f1e7bc357187e449479d627100102
[1] => test-685f1e7bc357187e449479d627d29390
)
Array two
Array
(
[0] => DF955298-A664-4FA7-9586-FCD4CF977777
[1] => DF955298-A664-4FA7-9586-FCD4CF988888
)
Expected Result
Array
(
[0] => Array
(
[key] => test-685f1e7bc357187e449479d627100102
[uuid] => DF955298-A664-4FA7-9586-FCD4CF977777
)
[1] => Array
(
[key] => test-685f1e7bc357187e449479d627d29390
[uuid] => DF955298-A664-4FA7-9586-FCD4CF988888
)
)
My code is for that result is mentioned below:
$record = array();
foreach ($keys_array as $key => $all_key) {
foreach ($uuid_array as $uuid_key => $all_uuid) {
$record[$key]['key'] = $all_key;
$record[$uuid_key]['uuid'] = $all_uuid;
}
}
My output sequence is not valid. Where is the problem
Array
(
[0] => Array
(
[key] => test-685f1e7bc357187e449479d627100102
[uuid] => DF955298-A664-4FA7-9586-FCD4CF977777
)
[1] => Array
(
[uuid] => test-685f1e7bc357187e449479d627d29390
[key] => DF955298-A664-4FA7-9586-FCD4CF988888
)
)
Simple solution:
$record = array();
foreach ($keys_array as $key => $all_key) {
$record[] = [
'key' => $all_key,
// get value under the same key from `$uuid_array`
'uuid' => $uuid_array[$key],
];
}

Convert order of array of array in php

I am trying to change the order of php array of array.
$arrKeysWithoutValues = array("id", "mobile", "stockCode");
$new_data = array();
foreach ($arrKeysWithoutValues as $key) {
//$list is array of array
$new_data[$key] = array_column($list, $key);
}
//what I received is as follows
//Array ( [id] => Array ( [0] => 4967 [1] => 4965 ) [mobile] => Array ( [0] => ****0030008 [1] => ****0030009 ) [stockCode] => Array ( [0] => sh600036 [1] => sh600036 ) )
//what I need is as follows
//Array ( [0] => Array ( [id] => 4967 [mobile] => ****0030008 [stockCode] => sh600036 ) [1] => Array ( [id] => 4965 [mobile] => ****0030009 [stockCode] => sh600036 ) )
What I received and what I needed is as in above comments. How can I solve this?
Sample structure of the list is as follows.
Array ( [0] => Array ( [id] => 4967 [stockCode] => sh600036 [mobile] => ****0030008 ) [1] => Array ( [id] => 4965 [stockCode] => sh600036 [mobile] => ****0030009 ) )
Don't touch and push the keys.
$new_data[$key] = array_column($list, $key);
// ^ this will yield different results
You use the order array and flip them into keys, then array_merge it with the original list, so then you keep the desired order. Like so:
$new_data = array();
$keys = array_flip($arrKeysWithoutValues); // flip and turn it to keys
foreach ($list as $l) {
$new_data[] = array_merge($keys, $l);
// ^^ merge them
}

How to create an array with the values of a nested array?

I have a multi-dimensional array that looks like this:
Array
(
[0] => Array
(
[name] => nonce
[value] => 4OdIiR6JhZ,1565652176,9c1abd8d4e7c717bb1c8a27552aabce58b3bf4b3
)
[1] => Array
(
[name] => firstName
[value] => Honkey
)
[2] => Array
(
[name] => lastName
[value] => McDonalds
)
)
and I want to get an array that looks like this:
Array
(
[nonce] => 4OdIiR6JhZ,1565652176,9c1abd8d4e7c717bb1c8a27552aabce58b3bf4b3
[firstName] => Honkey
[lastName] => McDonalds
)
I know that I could accomplish this by doing a foreach loop and creating a new array.
$newForm = [];
foreach ($something as $index => $item) {
$newIndex = $item['name'];
$newForm[$newIndex] = $item['value'];
}
But I am wondering if there is a better way to do this (perhaps using one of PHP's array functions)?
This is what the 3 parameter form of array_column is perfect for:
$output = array_column($input, 'value', 'name');
Output:
Array
(
[nonce] => 4OdIiR6JhZ,1565652176,9c1abd8d4e7c717bb1c8a27552aabce58b3bf4b3
[firstName] => Honkey
[lastName] => McDonalds
)
Demo on 3v4l.org
With foreach,
$result = [];
foreach($array as $v){
$result[$v["name"]] = $v["value"];
}
Check Demo

Multidimensional associative array: how to find array with same value?

I'm currently looking for a solution to this problem:
if I have something like that:
Array
(
[0] => Array
(
[id] => 1
[name] => Timer
)
[1] => Array
(
[id] => 2
[name] => Tub
)
[3] => Array
(
[id] => 1
[name] => Paper
)
[4] => Array
(
[id] => 4
[name] => Puppy
)
)
The goal I'd like to reach here is create a new array which contains the arrays with the same ID. So basically, at the end I'm gonna have two arrays: the first will contain element with different IDs and the second will contain element with the same ID.
Any tips? Thank you in advance!
One way is by mainly using array_filter()
// Gather ids and count
$id = array_count_values(array_column($array, 'id'));
// Filter not unique
$notUnique = array_filter($array, function($e) use ($id) {
return ($id[$e['id']] > 1);
});
// Filter unique
$unique = array_filter($array, function($e) use ($id) {
return !($id[$e['id']] > 1); // or ($id[$e['id']] == 1)
});
// Print result
print_r($notUnique);
echo '<br>';
print_r($unique);
Try this
<?php
$array = array(
array('id' => 1,'name' => 'Timer'),
array('id' => 2,'name' => 'Tub'),
array('id' => 1,'name' => 'Paper'),
array('id' => 4,'name' => 'Puppy')
);
$new = array();
foreach($array as $r)$new[$r['id']][] = $r['name'];
echo '<pre>';print_r($new);
?>
Output
Array
(
[1] => Array
(
[0] => Timer
[1] => Paper
)
[2] => Array
(
[0] => Tub
)
[4] => Array
(
[0] => Puppy
)
)

compare two associative array and display the difference

I have the following Two array results coming from MySQL query result.
Array One (Orignal-Data):
Array
(
[w_a] => Array
(
[0] => Array
(
[cod] => CRR
[pr] => LL
[aid] => VM2254
[gender] => m
[title] =>
)
)
[w_a_ml] => Array
(
)
[w_a_ol] => Array
(
)
[w_a_rl] => Array
(
[0] => Array
(
[rol] => 1
)
)
)
Array Two (Changed-Data)
Array
(
[w_a] => Array
(
[0] => Array
(
[cod] => CRR
[pr] => LL
[aid] => VM2254
[gender] => f
[title] => Mr
)
)
[w_a_ml] => Array
(
[0] => Array
(
[wl] => 255
[care] => Sahan
[heigh] =>
[adam] =>
[instance] => Look
)
)
[w_a_ol] => Array
(
)
[w_a_rl] => Array
(
[0] => Array
(
[rol] => 1
)
)
)
What I wan to achieve from the above two array is to compare and show the result in table format or Inside Form To each Field (Original and New-Change) like below.
FiledsN Original New Change
title Empty Mr
Wl Empty 255
Care Empty Sahan
gender m f
instance Empty Look
I've tried making the array a single array using this function:
function array_single($arr) {
if (!is_array($arr)) {
return FALSE;
}
$res = array();
foreach ($arr as $keys => $values) {
if (is_array($values)) {
$res = array_merge($res, array_single($values));
} else {
$res[$keys] = $values;
}
}
return $res;
}
And then comparing using this:
function diff($new,$old) {
$del=array_diff_assoc($old,$new);
$add=array_diff_assoc($new,$old);
return $diff=array("old"=>$del, "new"=>$add);
}

Categories