PHP un-nest all element in multidimensional array [duplicate] - php

This question already has answers here:
How to "flatten" a multi-dimensional array to simple one in PHP? [duplicate]
(23 answers)
Closed 3 years ago.
I have a multidimensional array in PHP and I want to un-nest all elements to bring them to the top level. Here is the array:
Array
(
[0] => Array
(
[id] => 1
[color] => red
)
[1] => Array
(
[0] => Array
(
[id] => 2
[color] => blue
)
[1] => Array
(
[0] => Array
(
[id] => 3
[color] => green
)
)
[2] => Array
(
[id] => 4
[color] => blue
)
)
[2] => Array
(
[id] => 5
[color] => purple
)
)
What I want end the end is this... so basically it loops over the array and any group it just unnests it. Sorry, I don't know the proper terminology. Is there PHP function for this? I've tried several solutions on stack but it moves all key values pairs up to the top and not just the array groups --- it just creates a mess.
(
[0] => Array
(
[id] => 1
[id] => red
)
[1] => Array
(
[id] => 2
[color] => blue
)
[2] => Array
(
[id] => 3
[color] => green
)
[3] => Array
(
[id] => 4
[color] => blue
)
[4] => Array
(
[id] => 5
[color] => purple
)
)
Thanks!

You can do it like this, check the Demo
$result = [];
array_walk_recursive($array,function(&$v)use($result){
$result[] = $v;
});
$result = array_chunk($result,2);
$result = array_map(function($v){return array("id"=>$v[0],"color"=>$v[1]);});
print_r($result);

You can unpack it by using array_walk_recursive
$i = 0;
array_walk_recursive($a, function($v,$k)use(&$r,&$i){
$r[$i][$k] = $v;
($k == 'color') ? $i++ :$i;
});
print_r($r);
Working example :- https://3v4l.org/YPT2M

Use simple generic recursion as below(no id, no color),
function flattenArray($arr = [])
{
$retArr = [];
foreach ($arr as $val) {
if (is_array($val)) {
$retArr[] = array_filter($val, function ($v) {
return !is_array($v);
});
$retArr = array_merge(array_filter($retArr), flattenArray($val));
}
}
return $retArr;
}
$arr = flattenArray($arr);
Demo
Output:-
Array
(
[0] => Array
(
[id] => 1
[color] => red
)
[1] => Array
(
[id] => 2
[color] => blue
)
[2] => Array
(
[id] => 3
[color] => green
)
[3] => Array
(
[id] => 4
[color] => blue
)
[4] => Array
(
[id] => 5
[color] => purple
)
)

Related

Convert nested associative array to single array in php [duplicate]

This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 10 months ago.
I have nested array with key & value pair. i want to convert it in single array.
/* This is current array */
Array
(
[id] => Array
(
[0] => 1
[1] => 2
)
[qty] => Array
(
[0] => 1
[1] => 1
)
[price] => Array
(
[0] => 364.41
[1] => 300
)
[amount] => Array
(
[0] => 364.41
[1] => 300
)
)
/*Now, I want this type of array*/
Array
(
[0] => Array
(
[id] => 1
[qty] => 1
[price] => 364.41
[amount] => 364.41
)
[1] => Array
(
[id] => 2
[qty] => 1
[price] => 300
[amount] => 300
)
)
I have tried array_walk and some other solutions but i could not find any proper solution
Thanks in advance
Main array is your nested array and Collection is the result you want
foreach($mainArray["id"] as $key => $value ){
$collection[$key] = ['id' => $value];
foreach(array_keys($mainArray) as $arrayKeysOfmainArray){
if(!array_key_exists($arrayKeysOfmainArray, $collection)){
$collection[$key][$arrayKeysOfmainArray] = $mainArray[$arrayKeysOfmainArray][$key];
}
}
}
print_r($collection);
$mainarray['id'] = Array(1,2,3);
$mainarray['qty'] = Array(1,1,4);
$mainarray['price'] = Array(364.41,300,500);
$mainarray['amount'] = Array(364.41,300,600);
$new = [];
foreach($mainarray as $key=> $singleArray){
if(count($singleArray) > 0){
foreach($singleArray as $childKey=> $value){
$new[$childKey][$key] = $value;
}
};
}`

How to merge three arrays according to common key in php

I have three arrays first array include ids and employees name and second array have monthly collection with employee ids and third array have daily collection with employee id and daily collection I want to merge these array with ids and name and dcollection and monthly collection but the desired output is not coming here my first array $ids is
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Rohit
)
[1] => stdClass Object
(
[id] => 2
[name] => Emop1
)
[2] => stdClass Object
(
[id] => 3
[name] => Pankaj
)
[3] => stdClass Object
(
[id] => 4
[name] => tejpal singh
)
)
second array $q1 is
Array
(
[0] => stdClass Object
(
[name] => Rohit
[id] => 1
[mcollecton] => 100
)
[1] => stdClass Object
(
[name] => Emop1
[id] => 2
[mcollecton] => 1222
)
)
third array $q2 is
Array
(
[0] => stdClass Object
(
[name] => Rohit
[id] => 1
[dcollecton] => 300
)
[1] => stdClass Object
(
[name] => Emop1
[id] => 2
[dcollecton] => 150
)
)
so far what I have tried
$new_array = array();
foreach($ids as $k) {
$q1n = array("id"=>$k->id,"name"=>$k->name);
foreach($q1 as $k1) {
if($k->id==$k1->id){
$mc = array("mc"=>$k1->mcollecton);
array_merge($q1n,$mc);
}
}
foreach($q2 as $k1){
if($k->id==$k1->id){
$dc = array("dc"=>$k1->dcollecton);
array_merge($q1n,$dc);
}
}
$a = array_merge($q1n,$mc);
$av = array_merge($q1n,$dc);
array_push($new_array,$q1n);
}
but the output is coming as
Array
(
[0] => Array
(
[id] => 1
[name] => Rohit
)
[1] => Array
(
[id] => 2
[name] => Emop1
)
[2] => Array
(
[id] => 3
[name] => Pankaj
)
[3] => Array
(
[id] => 4
[name] => tejpal singh
)
)
I want the output be like
Array
(
[0] => Array
(
[id] => 1
[name] => Rohit
[mcollection] => 100
[dcollection] => 300
)
[1] => Array
(
[id] => 2
[name] => Emop1
[mcollection] => 1222
[dcollection] => 150
)
[2] => Array
(
[id] => 3
[name] => Pankaj
[mcollection] => 0
[dcollection] => 0
)
[3] => Array
(
[id] => 4
[name] => tejpal singh
[mcollection] => 0
[dcollection] => 0
)
)
So I have tried many times but the desired output is not coming . please help me out how to get the desired output.
It seemed like that answer could be modified, or put in a function that you could call multiple times if needed to combine more than two arrays.
There's probably cleaner ways to handle this with array functions like array_merge or array_walk, but this is the general idea of how I might approach it. I haven't tested this, but maybe it's useful.
foreach($first as $key1 => $value){
foreach($second as $key2 => $value2){
// match the ids and check if array key exists on first array
if($value['id'] === $value2['id'] && empty($first[$key2])){
$first[$key][$key2] = $value2;
}
}
}
EDIT: Based on the answer you posted vs the question you asked, are you incrementing the collection numbers or just setting them? In other words why use +=? You should also be able to remove array_merge and array_push.
Below is geared more towards what you're trying to do. I haven't tested this either, but if you run into errors, post your code with the errors returned so that it's easier to debug:
foreach($ids as $k)
{
$thisArray = $newArray[] = array("id"=>$k->id,"name"=>$k->name);
foreach($q1 as $k1)
{
if($k->id == $k1->id && !empty($k1->mcollecton))
{
$thisArray['mc'] = $k1->mcollecton;
}
}
foreach($q2 as $k2)
{
if($k->id == $k2->id && !empty($k2->dcollecton))
{
$thisArray['dc'] = $k2->dcollecton;
}
}
}
// This should have both new collections fields on all array items
print_r($newArray)

Combining 2 Arrays when value is matched

So I have these arrays that is fetched from 2 different database, I would like to combine them in one array when the ['item_name'] and ['name'] is matched then getting the ['id'] from the Array2
I tried doing the in_array but since it's multi dimensional, I can't get the right output I want, I tried foreach also but I can't also get the right output or maybe I'm doing it wrong, I'm running out of idea how I could do the output I wanted.
Example Array1:
Array
(
[0] => Array
(
[item_id] => 1
[item_name] => Bag
[Color] => Purple
)
[1] => Array
(
[item_id] => 2
[item_name] => Pencil
[Color] => Yellow
)
[2] => Array
(
[item_id] => 3
[item_name] => Tumbler
[Color] => Blue
)
[3] => Array
(
[item_id] => 4
[item_name] => Shirt
[Color] => Red
)
)
Example Array2:
Array
(
[0] => Array
(
[id] => 11
[name] => Bag
)
[1] => Array
(
[id] => 22
[name] => Pencil
)
[2] => Array
(
[id] => 33
[name] => Tumbler
)
[3] => Array
(
[id] => 44
[name] => Shirt
)
[4] => Array
(
[id] => 55
[name] => Paper
)
[5] => Array
(
[id] => 66
[name] => Chair
)
[6] => Array
(
[id] => 4
[name] => Notebook
)
)
So my expected output would be:
Array
(
[0] => Array
(
[id] => 11
[name] => Bag
[Color] => Purple
)
[1] => Array
(
[id] => 22
[name] => Pencil
[Color] => Yellow
)
[2] => Array
(
[id] => 33
[name] => Tumbler
[Color] => Blue
)
[3] => Array
(
[id] => 44
[name] => Shirt
[Color] => Red
)
)
You can create a map with the names and the ID from the second array and then loop to modify the first one.
Consider the following code:
$a1 = array("item_id" => 1, "item_name" => "Bag", "Color" => "Purple");
$a2 = array("item_id" => 2, "item_name" => "Pencil", "Color" => "Yellow");
$a3 = array("item_id" => 3, "item_name" => "Tumbler", "Color" => "Blue");
$b1 = array("item_id" => 11, "item_name" => "Bag");
$b2 = array("item_id" => 22, "item_name" => "Pencil");
$b3 = array("item_id" => 33, "item_name" => "Tumbler");
$arr1 = array($a1, $a2, $a3);
$arr2 = array($b1, $b2, $b3);
$map = []; // here keys are names and value are the id
foreach($arr2 as $elem)
$map[$elem["item_name"]] = $elem["item_id"];
$ans = [];
foreach ($arr1 as $elem) {
if (array_key_exists($elem["item_name"], $map)) {
$elem["item_id"] = $map[$elem["item_name"]];
$ans[] = $elem;
}
}
echo print_r($ans);
In this way you achieve complexity of O(n) instead of O(n^2) if trying nested for-loop
Try by using foreach loop.
Check if in foreach loop if any index value match with another array then create a new array with all those values.
You can use counter here to get the value of array inside loop.
Been trying to simplify my code earlier and I think I got it, thanks to anju and David Winder, if anyone interested how I did it, this is how:
index = 0;
foreach ($array1 as $val){
foreach ($array2 as $val2){
if ($val['item_id'] == $val2['id']){
$filtered[$index]['id'] = $val2['id'];
$filtered[$index]['name'] = $val2['name'];
$filtered[$index]['color'] = $val['color'];
$index++;
}
}
}

Split an array into a MD array every nth line

bit of a question here. Ive got an array that contains data which has been parsed from a website using all our favourite php functions such as array_map.
The array is current 3 sub arrays deep.
Here is the code I am using:
for ($tcid = 1; $tcid <= count($categories); $tcid++) {
$catHeader[$tcid] = $categories[$tcid][0];
$event[$i]['tickets'] = $categories;
unset($categories[$tcid][0]);
$categories[$tcid] = array_map('trim', $categories[$tcid]);
$categories[$tcid] = array_values($categories[$tcid]);
$ab = 0;
for ($b = 0; $b <= count($categories[$tcid]); $b++) {
if ($categories[$tcid][$b] == "" || !$categories[$tcid][$b] || $categories[$tcid][$b] == null) {
unset($categories[$tcid][$b]);
}
}
}
and the array looks something like....
[1] => Array (
[data] => Array ( ...
)
[tickets] => Array (
[1] => Array (
[0] => xxx
[1] => etc
[3] => etc2
)
[2] => (
[0] => Std1
[1] => 10 / 10
[2] => £20.00
[3] => £200.00
[4] => Std2
[5] => 100 / 100
[6] => £13.00
[7] => £1,300.00
[8] => Std3
[9] => 10 / 320
[10] => £15.00
[11] => £150.00
)
)
)
My question to you today, is how on earth do I split the array every 4 \n's or array keys as they're known and explode each 4 into a further sub array?
So that Std1, Std2, Std3 will be their own sub array with its associated data of the 2nd key of tickets, but also doing this for every sub array of tickets that has more than 1 set of data (a set of data being 4 array keys).
I've tried all sorts but can't get it to work.
See below of how I want it to look.
[1] => Array (
[data] => Array ( ...
)
[tickets] => Array (
[1] => Array (
[0] => xxx
[1] => etc
[3] => etc2
)
[2] => (
[0] => Array (
[0] => Std1
[1] => 10 / 10
[2] => £20.00
[3] => £200.00
)
[1] => Array (
[0] => Std2
[1] => 100 / 100
[2] => £13.00
[3] => £1,300.00
)
[2] => Array (
[0] => Std3
[1] => 10 / 320
[2] => £15.00
[3] => £150.00
)
)
)
)
Thanks
As noted in the comments, you'd be best off handling your array by-reference to modify it's original contents somewhere within your loops
Provided the array groupings you want to chunk are in groups of 4, you could array_chunk() it:
$array['tickets'][2] = array_chunk($array['tickets'][2], 4);

Change several ARRAY into new ARRAYS [duplicate]

This question already has answers here:
Combine arrays in PHP [duplicate]
(4 answers)
Closed 10 months ago.
I would like to know how to change the contents from several ARRAYS into new ARRAYS.
I have this 3 vars with a ARRAY each, lets say the first var is $number and it has this array:
Array
(
[0] => 1
[1] => 3
[2] => 9
)
The second var is $item and it has this:
Array
(
[0] => house
[1] => car
[2] => bike
)
And the third is $color and it has this:
Array
(
[0] => red
[1] => white
[2] => black
)
How can I change the contents and create new arrays like this:
Array
(
[0] => 1
[1] => house
[2] => red
)
Array
(
[0] => 3
[1] => car
[2] => white
)
Array
(
[0] => 9
[1] => bike
[2] => black
)
You can use array_map:
<?php
$number = [1,3,9];
$item = ['house','car','bike'];
$color = ['red','white','black'];
$res = array_map(null, $number, $item, $color);
print_r($res);
?>
which will output a single array of arrays that you want:
Array
(
[0] => Array
(
[0] => 1
[1] => house
[2] => red
)
[1] => Array
(
[0] => 3
[1] => car
[2] => white
)
[2] => Array
(
[0] => 9
[1] => bike
[2] => black
)
)
You can make a callback function with array_map() that returns each value together:
$result = array();
function merge_arrays($a,$b,$c){
return array($a,$b,$c);
}
$result = array_map("merge_arrays",$number,$item,$color);
DEMO

Categories