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

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

Related

How to delete the value inside the array in PHP

I want to delete the ['Phone'] inside my array.
i tried foreach and unset but only the first array delete the ['Phone'].
my example array below.
Array
(
[0] => Array
(
[Name] => ads
[Phone] => 32132
)
[1] => Array
(
[Name] => ads
[Phone] => 321322
)
[2] => Array
(
[Name] => ads
[Phone] => 3213222
)
)
and my expected array.
Array
(
[0] => Array
(
[Name] => ads
)
[1] => Array
(
[Name] => ads
)
[2] => Array
(
[Name] => ads
)
)
You can use array_walk
array_walk($arr, function(&$v, $k){
unset($v['Phone']);
});
If all you want is to fetch the names, you can just pluck those using array_column().
$array = array_column($array, "Name");
Live demo at https://3v4l.org/VJTli
You can use map() function of Laravel Collection. and alter your original array however you want.
$newArray = collect($oldArray)->map(function($element) {
return [
'name' => $element['name'];
];
})->toArray();
Qirel's answer is faster I would imagine if you only have "name" and "phone". Another alternative that is easy on the eyes is:
foreach ($array as &$val) {
unset($val["Phone"]);
}

JS array to combine into one array

I have following js array using serialisedArray -
Array
(
[0] => Array
(
[name] => sub_maintenance_template[1][maintenance_location_id]
[value] => 54321
)
[1] => Array
(
[name] => sub_maintenance_template[1][maintenance_problem_id]
[value] => 65432
)
[2] => Array
(
[name] => sub_maintenance_template[1][maintenance_priority_id]
[value] => 76896
)
[3] => Array
(
[name] => sub_maintenance_template[1][description]
[value] => sample description
)
)
Expected array -
[sub_maintenance_template] => Array (
[1] =>
(
[maintenance_location_id]=> 54321
[maintenance_problem_id]=> 65432
[maintenance_priority_id]=>76896
[description]=> sample description
)
)
I tried like this-
foreach( $tableData as $key => $value ) {
echo $key;
$newArray['sub_maintenance_template'][3][] = $value['name'];
$newArray['sub_maintenance_template'][3][] = $value['value'];
}
Even though I iterate it through foreach but failed to get desired output. IS there any way to get desired one?
It would be better to pass these as actual arrays in GET or POST, but since the string in name is how arrays would be passed in a URL query string, you can use parse_str:
foreach($array as $values) {
parse_str("{$values['name']} = {$values['value']}", $result);
}
print_r($result);
Or another way; extract and build key/value pairs to build a query string and then parse it:
parse_str(http_build_query(array_column($array, 'value', 'name')), $result);
print_r($result);

PHP How to restructure an array?

I have an array that I'd like to restructure. I want to group items by turn. I can figure out how to extract data from the array using foreach($arr['history'] as $obj) my issue is with populating a new array using a loop.
Currently it looks like this:
Array (
[history] => Array (
[id] => 23452435
[legend] => Array (
[0] => Array (
[player] => me
[turn] => 1
[card] => Array (
[name] => foo
)
)
[1] => Array (
[player] => me
[turn] => 1
[card] => Array (
[name] => bar
)
)
[2] => Array (
[player] => opponent
[turn] => 1
[card] => Array (
[name] => derp
)
)
[3] => Array (
[player] => opponent
[turn] => 2
[card] => Array (
[name] => hoo
)
)
)
))
I want it to look like the following, but I can't figure out how to automatically create and populate this structure. This is an array with a sub-array for each turn, containing an array for me and opponent
Array (
[0] => Array (
[me] => Array (
[0] => foo
[1] => bar
)
[opponent] = Array (
[0] => derp
)
)
[1] => Array (
[me] => Array ()
[opponent] => Array (
[0] => hoo
)
))
Thanks.
Edit:
This is what I needed. Thanks for the answers.
$result = [];
foreach ($arr['history'] as $historyItem) {
foreach ($historyItem['legend'] as $list) {
$result[$list['turn']][$list['player']][] = $list['card']['name'];
}
}
Try this:
$result = [];
foreach ($data['history']['legend'] as $list) {
$result[$list['turn']-1][$list['player']][] = $list['card']['name'];
}
Fiddle it! http://ideone.com/BtKOKJ
You can just start adding data to the new array. PHP is extremely forgiving.
$historyByTurns = array();
foreach ($arr['history'] as $historyItem) {
foreach ($historyItem['legend'] as $legendItem) {
$turn = $legendItem['turn'];
$player = $legendItem['player'];
if (!array_key_exists($turn, $historyByTurns)) {
$historyByTurns[$turn] = array();
}
if (!array_key_exists($player, $historyByTurns[$turn])) {
$historyByTurns[$turn][$player] = array();
}
foreach ($legendItem as $card) {
$historyByTurns[$turn][$player][] = $card['name'];
}
}
}
You will have to test it, as I have no way to do that ATM.

merge recursive on inner arrays of multidimensional array 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);

Remove duplicated values from nested array

I'm getting stack-removing duplicated keys and assigning them to a new array.
My array:
array (
[1] => Array
(
[name] => name1
[actions] => add
)
[2] => Array
(
[name] => name1
[actions] => remove
)
[3] => Array
(
[name] => name2
[actions] => dosomething1
)
[4] => Array
(
[name] => name2
[actions] => dosomething1
)
)
What I am trying to achieve:
array (
[1] => Array
(
[name] => name1
[actions] => add
[actions] => remove
)
[2] => Array
(
[name] => name2
[actions] => dosomething1
[actions] => dosomething1
)
)
What i have tried:
public function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
It is incorrectly returning the same array. Any help would be appreciated.
You cannot have two array keys with the save values (so two actions elements for a given element would not be possible) What you can do is have a single action element with multiple values in it.
$results = array();
foreach ($array as $v){
if (!isset($results[$v["name"]]){
$results[$v["name"]] = array("name"=>$v["name"], "actions"=>array($v["actions"]));
} else {
$results[$v["name"]]["actions"][] = $v["actions"];
}
}
if you want to remove the string keys on the top level array you can then do.
$results = array_values($results);

Categories