Transpose 2d array with inconsistent column structure [duplicate] - php

This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 6 months ago.
Array
(
[0] => Array
(
[color] => Brown
)
[1] => Array
(
[color] => Green
)
[2] => Array
(
[width] => 34
)
)
i need to make it like this
[color] => Array
(
[0] => green
[1] => brown
)
[width] => Array
(
[0] => 34
)
)
i am trying with all the array tools. But i cant make it like i want it.

This is fairly simple with array_column() (requires PHP >= 5.5.0):
$result = array[
'color' => array_column($arr, 'color'),
'width' => array_column($arr, 'width')
];
Live fiddle: https://eval.in/81746
If you do not know the keys beforehand, here is another solution using array_walk_recursive():
$result = [];
array_walk_recursive($arr, function($value, $key) use (&$result) {
if (!isset($result[$key])) {
$result[$key] = [];
}
$result[$key][] = $value;
});
Live fiddle: https://eval.in/81745

So you want to merge the arrays recursively... if only such an array_merge_recursive function existed... Why don't you try this:
$a = array(
array('colour' => 'green'),
array('colour' => 'blue'),
array('width' => 123)
);
$result = array();
foreach($a as $arr)
{
$result = array_merge_recursive($result, $arr);
}
var_dump($result);
That worked pretty darn well for me, as you can see for yourself here, too
True, in the given example width won't be an array, so you get:
array('colour' => array('green','blue'),'width' => 123);
If you need everything to be an array, then a dirty fix would be to use a cast:
foreach($result as $k => $v) $result[$k] = (array) $v;
Reassigning the $result values a second time, only casting them as an array ensures that all values will, evidently, be arrays. An array that is cast to an array will remain unchanged, just like (int) 1 still evaluates to 1. A primitive value (strings, integers, doubles,...) will be wrapped int an array, but an object will be transformed into an array, so be careful. If objects are likely to occur in this array:
foreach($result as $k => $v) $result[$k] = is_array($v) ? $v : array($v);
is probably the safer bet. However, I chose not to go for this approach as I still find it pretty tedious and silly to wrap everything up into an array, containing only 1 value...
For those of you with a strange preference for unmaintainable code, the following one-liner is a condensed, but notice free & working example of the same code:
foreach($a as $arr) $result = array_merge_recursive(isset($result) ? $result : array(), $arr);
This is as a response to Stuart Wakefield who suggested a one-liner using call_user_func_array, which is something I'll always oppose, for as long as I live and breathe, BTW...

I guess this should do it, especially if you don't know what keys you will have:
foreach ($original_array as $val1)
foreach ($val1 as $key2=>$val2)
$merged_array[$key2][] = $val2;

just use foreach like below --
arrayName = your original array --
foreach($arrayName as $newArr){
if($newArr['color']){
$tempArr['color'][] = $newArr['color'];
}
if($newArr['width']){
$tempArr['width'][] = $newArr['width'];
}
}

Try using array_merge_recursive OR array_column

Building upon Elias's array_merge_recursive answer, the following introduces a small fix to turn single item merge into an array:
/* This version uses the function array_merge_recursive to collect
* all of the values for the nested arrays by key
*
* #see http://willem.stuursma.name/2011/09/08/parallel-array_map-with-hiphop/
* #see http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/
* for why for loops are better than array_map in general
*/
$result = array_map(function($item) {
/* The array_merge_recursive function doesn't add
* values to an array if there was only one found
* if the item isn't an array, make it an array
*/
return is_array($item) ? $item : array($item);
/* Calls the array_merge_recursive function applying all of
* the nested arrays as parameters.
*
* #see http://php.net/array_merge_recursive
* #see http://www.php.net/call_user_func_array
*/
}, call_user_func_array('array_merge_recursive', $arr));
Produces:
Array
(
[color] => Array
(
[0] => green
[1] => brown
)
[width] => Array
(
[0] => 34
)
)
Instead of:
Array
(
[color] => Array
(
[0] => green
[1] => brown
)
[width] => 34
)
Alternatively, a dynamic approach to ComFreek's array_column solution.
This gives you the array of the keys:
/* Gets the keys of the nested arrays as a single array of keys by first
* mapping the nested arrays to an array of keys they contain and then
* by merging these arrays and killing duplicates
*
* #see http://php.net/function.array-unique
* #see http://www.php.net/call_user_func_array
* #see http://www.php.net/array_merge
* #see http://www.php.net/array_map
*/
$keys = array_unique(call_user_func_array('array_merge', array_map(function($item) {
/* Replaces the nested array of keys and values with an array
* of keys only in the mapped array
*
* #see http://www.php.net/array_keys
*/
return array_keys($item);
}, $arr)));
As:
Array
(
[0] => color
[1] => width
)
Which can be used with this snippet:
/* Combines the array of keys with the values from the nested
* arrays.
*
* #see http://php.net/array_combine
* #see http://www.php.net/manual/en/function.array-map.php
*/
$result = array_combine($keys, array_map(function($key) use($arr) {
/* Collects the values from the nested arrays
*
* #see http://php.net/array_column
*/
return array_column($arr, $key);
}, $keys));
To create the desired output:
Array
(
[color] => Array
(
[0] => green
[1] => brown
)
[width] => Array
(
[0] => 34
)
)
Note: functional calls can be beneficial in most languages over an imperative style although it does require a shift mentally. Functional patterns open up the possibilities of low level optimizations that otherwise wouldn't be possible. Array map, for example, could be executed in parallel, whereas a for loop cannot, the for loop will always have a restriction that it must execute sequentially.

Related

How to split array into all possible combinations

How can I loop through an array, split it into two arrays and run a function for each possible combination? Order does not matter.
// Original array
$array = array('a','b','c','d','e');
// Result 1
array('a');
array('b','c','d','e');
// Result 2
array('a', 'b');
array('c','d','e');
// Result 3
array('a', 'c');
array('b','d','e');
And so on...
Here's my take at this:
<?php
$ar = ['a','b','c','d','e'];
function permuteThrough($ar, $callback, $allowMirroredResults = true, $mode = 'entry', $desiredLeftCount = null, $left = [], $right = [])
{
switch($mode)
{
case 'entry':
// Logic:
// Determine how many elements we're gonna put into left array
$len = $allowMirroredResults ? count($ar) : floor(count($ar)/2);
for($i=0; $i <= $len; $i++)
{
call_user_func(__FUNCTION__, $ar, $callback, $allowMirroredResults, 'permute',$i);
}
break;
case 'permute':
// We have nothing left to sort, let's tell our callback
if( count($ar) === 0 )
{
$callback($left,$right);
break;
}
if( count($left) < $desiredLeftCount )
{
// Note: PHP assigns arrays as clones (unlike objects)
$ar1 = $ar;
$left1 = $left;
$left1[] = current(array_splice($ar1,0,1));
call_user_func(__FUNCTION__, $ar1, $callback, $allowMirroredResults, 'permute', $desiredLeftCount, $left1, $right);
}
// This check is needed so we don't generate permutations which don't fulfill the desired left count
$originalLength = count($ar) + count($left)+count($right);
if( count($right) < $originalLength - $desiredLeftCount )
{
$ar2 = $ar;
$right1 = $right;
$right1[] = current(array_splice($ar2,0,1));
call_user_func(__FUNCTION__, $ar2, $callback, $allowMirroredResults, 'permute', $desiredLeftCount, $left, $right1);
}
break;
}
}
function printArrays($a,$b)
{
echo '['.implode(',',$a).'],['.implode(',',$b)."]\n";
}
permuteThrough($ar, 'printArrays', true); // allows mirrored results
/*
[],[a,b,c,d,e]
[a],[b,c,d,e]
[b],[a,c,d,e]
[c],[a,b,d,e]
[d],[a,b,c,e]
[e],[a,b,c,d]
[a,b],[c,d,e]
[a,c],[b,d,e]
[a,d],[b,c,e]
[a,e],[b,c,d]
[b,c],[a,d,e]
[b,d],[a,c,e]
[b,e],[a,c,d]
[c,d],[a,b,e]
[c,e],[a,b,d]
[d,e],[a,b,c]
[a,b,c],[d,e]
[a,b,d],[c,e]
[a,b,e],[c,d]
[a,c,d],[b,e]
[a,c,e],[b,d]
[a,d,e],[b,c]
[b,c,d],[a,e]
[b,c,e],[a,d]
[b,d,e],[a,c]
[c,d,e],[a,b]
[a,b,c,d],[e]
[a,b,c,e],[d]
[a,b,d,e],[c]
[a,c,d,e],[b]
[b,c,d,e],[a]
[a,b,c,d,e],[]
*/
echo "==============\n"; // output separator
permuteThrough($ar, 'printArrays', false); // doesn't allow mirrored results
/*
[],[a,b,c,d,e]
[a],[b,c,d,e]
[b],[a,c,d,e]
[c],[a,b,d,e]
[d],[a,b,c,e]
[e],[a,b,c,d]
[a,b],[c,d,e]
[a,c],[b,d,e]
[a,d],[b,c,e]
[a,e],[b,c,d]
[b,c],[a,d,e]
[b,d],[a,c,e]
[b,e],[a,c,d]
[c,d],[a,b,e]
[c,e],[a,b,d]
[d,e],[a,b,c]
*/
My permuteThrough function takes three arguments.
The array, the callback, and an optional boolean indicating whether or not you want to allow mirrored results.
The logic is pretty straight forward:
First decide how many elements we want to put into our left array.
Then Recursively call the function like so:
Our working array with the remaining elements to sort.
Shift an element off and put it into the left array. The result gets sent to another layer of recursion.
Shift an element off and put it into the right array. The result gets sent to another layer of recursion.
If there's no elements left to shift off, call our callback with the resulting left and right arrays.
Finally, make sure we're not going over the desired left array element size determined by the for loop at the beginning and make sure the right size doesn't become so big that it makes the desired left size impossible to satisfy. Normally this would be done by two separate functions. One to decide how many elements should go into the left array. And one to be used for recursion. But instead I tossed in another argument to the recursion function to eliminate the need for a separate function so it can all be handled by the same recursive function.
This is the best I can do:
class Combos
{
/**
* getPossible then getDivide
*
* #param array $input
* #return array
*/
public function getPossibleAndDivided( array $input )
{
return $this->getMultiShiftAndDivided( $this->getPossible( $input ) );
}
/**
* return all possible combinations of input
*
* #param array $input
* #return array
*/
public function getPossible( array $inputs )
{
$result = [];
if ( count( $inputs ) <= 1 ) {
$result = $inputs;
} else {
$result = array();
foreach($inputs as $input){
//make it an array
$first = [ $input ];
//get all inputs not in first
$remaining = array_diff( $inputs, $first );
//send the remaining stuff but to ourself
$combos = $this->getPossible( $remaining );//recursive
//iterate over the above results (from ourself)
foreach( $combos as $combo ) {
$last = $combo;
//convert to array if it's not
if( !is_array( $last ) ) $last = [ $last ];
//merge them
$result[] = array_merge( $first, $last );
}
}
}
return $result;
}
/**
* shift and divide a multi level array
*
* #param array $array
* #return array
*/
public function getMultiShiftAndDivided( array $mArray )
{
$divided = [];
foreach ( $mArray as $array ) {
$divided = array_merge($divided, $this->getShiftAndDivided( $array ));
}
return $divided;
}
/**
* shift and divide a single level array
*
* #param array $array
* #return array
*/
public function getShiftAndDivided( array $array )
{
$divided = [];
$array1 = [];
while( count( $array ) ){
$array1[] = array_shift( $array );
$divided[] = [ $array, $array1 ];
}
return $divided;
}
}
How it works
Top level, I don't want to get into all the details. This is basically a 2 step process or at least it was easier to figure it out that way. I built it in a class to keep everything neat. It also allows better unit testing and re-usability.
This requires 2 operations, or at least it was easier for me to do it in 2 instead of as 1. They are combined in this method
public function getPossibleAndDivided( array $input )
{
return $this->getMultiShiftAndDivided( $this->getPossible( $input ) );
}
This is the main reason I made it a class, to keep everything packaged nicely together. I would call this a wrapper method.
Step One
$Combos->getPossible(array $input)
if only one item remains, return $inputs.
this is all the combinations it can ever have (its just a single element after all).
else It iterates thought $inputs with foreach as $input
Wraps $input as an array named $first
this is a single element from $inputs
Gets the remaining elements in $inputs in a non-destructive way as $remaining
using array_diff we need both elements as arrays (see aabove)
recursive call to $this->getPossible($remaining) (see #1) and returns as $combos
Iterates over $combos foreach as $combo
$combo is assigned to $last and turned into an array, if its not
sometimes combo is an array with several elements
sometimes is a single element. It depends on the recursive call
We add to our result set the merger of $first and $last
we need both as arrays so we can merge, without causing nesting
End Anything in $result is returned.
This basically rotates though all the combinations of the array and returns them in an array like this:
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
)
[1] => Array
(
[0] => a
[1] => b
[2] => c
[3] => e
[4] => d
)
[2] => Array
(
[0] => a
[1] => b
[2] => d
[3] => c
[4] => e
)
...
[117] => Array
(
[0] => e
[1] => d
[2] => b
[3] => c
[4] => a
)
[118] => Array
(
[0] => e
[1] => d
[2] => c
[3] => a
[4] => b
)
[119] => Array
(
[0] => e
[1] => d
[2] => c
[3] => b
[4] => a
)
)
Yes it returns 119 results, no I will not include them all.
Step Two
Don't forget the above output is a multi-dimensional array (this is important below).
$Combos->getMultiShiftAndDivided(array $mArray)
This method is intended to be used with multi-dimensional arrays (hence its name). We get this from "Step 1". Its basically a wrapper for $Combos->getShiftAndDivided($array)
Iterates over $mArray foreach as $array
It calls $this->getShiftAndDivided($array) returns and merges with $divided.
there was no need to store the results, so I didn't waste a variable on it.
Output example:
$input = array(array('a','b','c','d','e'));
print_r($combos->getMultiShiftAndDivided($input));
Array
(
[0] => Array
(
[0] => Array
(
[0] => b
[1] => c
[2] => d
[3] => e
)
[1] => Array
(
[0] => a
)
)
....
[4] => Array
(
[0] => Array
(
)
[1] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
)
)
)
$Combos->getShiftAndDivided(array $array)
This method is intended to be used single level arrays.
Loops as long as the count of $array is more then 0, while loop
$array1 gets the first element from $array added and that element is removed from $array (destructively)
we store both $array and $array1 in our results $divided
this records there current "state" at that moment
when there are no more items in $array we return our results
Output example:
$input = array('a','b','c','d','e');
print_r($combos->getShiftAndDivided($input));
Array
(
[0] => Array
(
[0] => Array
(
[0] => b
[1] => c
[2] => d
[3] => e
)
[1] => Array
(
[0] => a
)
)
....
[4] => Array
(
[0] => Array
(
)
[1] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
)
)
)
Basically this shifts the elements of a single array to two result arrays and records their state on each shift. I made it 2 functions so that it could be tested easier and be re-used easier.
Another issue is its kind of hard to check for multi-dimensional arrays. I know how to do it, but I didn't feel like it because it's kind of ugly and there is a better way. I say that because its possible to use a one level array in what is getMultiShiftAndDivided and it wouldn't give you what you would expect. Probably you would get an error like this:
//I say probably, but I actually test it ... lol
Warning: array_shift() expects parameter 1 to be array
Which could be confusing, one could think the code is buggered. So by having the second method call with a type set into it getShiftAndDivided( array $array ). When the wrapping method tries to call this with a string its going to blow up, but in a better way:
Catchable fatal error: Argument 1 passed to Combos::getShiftAndDivided() must be of the type array, string given
Hopefully that makes sense, it's something I always try to do in cases like this. It just makes life easier in the long run. Both function return the data in the same format, which is convenient (your welcome).
Summary
So the sum of what this does, is find all the combinations of our input, then it takes those and breaks each one into shifted and divided up array. There for it stands to reason that we will have all the possible combinations divided up into 2 arrays anyway possible. Because that is pretty much exactly what I said.
Now I am not 100% it does that, you can check them if you want, it returns like 599 elements at the end. So good luck on that, I would suggest testing just the results of $combos->getPossible($input). If that has all the combinations like it should, then this will have all that it needs. I am not sure if it returns duplicates, I don't think that was specified. But I didn't really check it.
You can call the main method like this:
$input = array('a','b','c','d','e');
print_r((new Combos)->getPossibleAndDivided($input));
Test It!
P.S. I spell breaks as brakes, but I can write code this, go figure...

replace duplicate fom stdclass array php [duplicate]

This question already has answers here:
How can I remove duplicates in an object array in PHP?
(2 answers)
Closed 8 years ago.
When I print $online_performers variable I want to get a unique value for id 2. Do I need to convert them in standard array first or is that possible without it? (remove all duplicates).Please check my new code for this.
Array
(
[0] => stdClass Object
(
[id] => 1
[username] => Sample1
)
[1] => stdClass Object
(
[id] => 2
[username] => Sample1
)
[2] => stdClass Object
(
[id] => 2
[username] => Sample1
)
[3] => stdClass Object
(
[id] => 4
[username] => Sample4
)
)
to
Array
(
[0] => stdClass Object
(
[id] => 1
[username] => Sample1
)
[1] => stdClass Object
(
[id] => 4
[username] => Sample4
)
)
PHP has a function called array_filter() for that purpose:
$filtered = array_filter($array, function($item) {
static $counts = array();
if(isset($counts[$item->id])) {
return false;
}
$counts[$item->id] = true;
return true;
});
Note the usage of the static keyword. If used inside a function, it means that a variable will get initialized just once when the function is called for the first time. This gives the possibility to preserve the lookup table $counts across multiple function calls.
In comments you told, that you also search for a way to remove all items with id X if X appears more than once. You could use the following algorithm, which is using a lookup table $ids to detect elements which's id occur more than ones and removes them (all):
$array = array("put your stdClass objects here");
$ids = array();
$result = array();
foreach($array as $item) {
if(!isset($ids[$item->id])) {
$result[$item->id]= $item;
$ids[$item->id] = true;
} else {
if(isset($result[$item->id])) {
unset($result[$item->id]);
}
}
}
$result = array_values($result);
var_dump($result);
If you don't care about changing your keys you could do this with a simple loop:
$aUniq = array ();
foreach($array as $obj) {
$aUniq[$obj->id] = $obj;
}
print_r($aUniq);
Let's say we have:
$array = [
//items 1,2,3 are same
(object)['id'=>1, 'username'=>'foo'],
(object)['id'=>2, 'username'=>'bar'],
(object)['id'=>2, 'username'=>'baz'],
(object)['id'=>2, 'username'=>'bar']
];
Then duplication depends of what do you mean. For instance, if that's about: two items with same id are treated as duplicates, then:
$field = 'id';
$result = array_values(
array_reduce($array, function($c, $x) use ($field)
{
$c[$x->$field] = $x;
return $c;
}, [])
);
However, if that's about all fields, which should match, then it's a different thing:
$array = [
//1 and 3 are same, 2 and 3 are not:
(object)['id'=>1, 'username'=>'foo'],
(object)['id'=>2, 'username'=>'bar'],
(object)['id'=>2, 'username'=>'baz'],
(object)['id'=>2, 'username'=>'bar']
];
You'll need to identify somehow your value row. Easiest way is to do serialize()
$result = array_values(
array_reduce($array, function($c, $x)
{
$c[serialize($x)] = $x;
return $c;
}, [])
);
But that may be slow since you'll serialize entire object structure (so you'll not see performance impact on small objects, but for complex structures and large amount of them it's sounds badly)
Also, if you don't care about keys in resulting array, you may omit array_values() call, since it serves only purpose of making keys numeric consecutive.

How to shift 2D array in PHP

Hi this is my 2D array format. I want to remove 1st inside array.
Array
(
[0] => Array
(
[0] => Array
(
[type] => section-open
)
)
[1] => Array
(
[0] => Array
(
[type] => section-close
)
)
)
I want to remove all inside array and return it like this
Array
(
[0] => Array
(
[type] => section-open
)
[1] => Array
(
[type] => section-close
)
)
I tried array_shift function it's not working...
Update: This was based on the example the user gave, but he expected it to work for arrays with more than one element.
array_shift() removes the first element of an array, but that's not what you want.
You have to build something yourself.
Something like:
$result = array();
foreach($my_array as $element)
{
$result[]=$element[0];
}
Since you probably want a real 2d shift I made a function which does that, removing the first level in the array, but keeping ALL the items in the second level.
Here is a working example:
http://codepad.org/H7iaTI1E
And the function:
/**
* Removes first level in an array, returning the 2nd level elements as an array
* #param array Array to process
* #return 2nd level items from the given array
*/
function array2dshift(array $array) {
$res = array();
foreach($array as $lvl1) {
foreach($lvl1 as $item) {
$res[] = $item;
}
}
return $res;
}

How to convert a 2-dim array of strings into 1-dim array of trimmed, unique values?

I have an array whose values are all arrays of a specific format that looks like this:
Array
(
[0] => Array
(
[0] => '8227'
[1] => ' 8138'
)
[1] => Array
(
[0] => '8227'
[1] => ' 8138'
[2] => ' 7785'
)
)
and I would like to have this:
Array
(
[0] => 8227
[1] => 8138
[2] => 7785
)
How can I do this ?
$result = array();
foreach ($input as $sub) { // Loop outer array
foreach ($sub as $val) { // Loop inner arrays
$val = trim($val);
if (!in_array($val, $result)) { // Check for duplicates
$result[] = $val; // Add to result array
}
}
}
$result = array();
foreach($array as $arr){
$result = array_merge($result, $arr);
}
$result = array_unique($result);
array_merge_recursive() can be used to flatten the array. Then, array_unique() to get the unique values, with array_values() to "reindex" the resultant array.
$flat = call_user_func_array('array_merge_recursive', $subject);
$uniq = array_values(array_unique($flat));
<?php
$array = array(
0 => array(
0 => 8227,
1 => 8138
),
1 => array(
0 => 8227,
1 => 8138,
2 => 7785
)
);
$newArray = array();
array_walk_recursive($array, function($item, $key) use(&$newArray) {
if(!in_array($item, $newArray)) {
$newArray[] = $item;
}
});
print_r($newArray);
?>
I don't like the idea of iterated calls of in_array() since it can cause a bit of drag on big arrays.
Now, my methods to follow are probably not going to set any speed records (I didn't bother to benchmark), but I thought I would post a couple of unorthodox approaches in case they may inspire future readers.
Method #1:
convert the multi-dimensional array to a json string
split the string on all non-digital substrings (this also trims the values)
eliminate duplicates using array_flip()
re-index the resultant array using array_keys() (output values are integer-type)
Method #2:
convert the multi-dimensional array to a json string
extract the words (which in this case include numbers and there aren't any letters to worry about)
eliminate duplicates using array_flip()
reindex the resultant array using array_keys() (output values are integer-type)
Code: (Demo)
$array = [['8227', '8138'], [' 8227', ' 8138', ' 7785']];
echo "regex method: ";
var_export(
array_keys(
array_flip(
preg_split(
'/\D+/',
json_encode($array),
0,
PREG_SPLIT_NO_EMPTY
)
)
)
);
echo "\n\nnon-regex method: ";
var_export(
array_keys(
array_flip(
str_word_count(
json_encode($array),
1,
'0..9'
)
)
)
);
Output:
regex method: array (
0 => 8227,
1 => 8138,
2 => 7785,
)
non-regex method: array (
0 => 8227,
1 => 8138,
2 => 7785,
)
If either of these methods perform well, it will be because they don't make iterated function calls.
p.s. Okay, because I was curious, I just did a very small / unofficial speed test on my two methods and DaveRandom's method (only 1000 iterations using the OP's data - I didn't want to abuse 3v4l.org) and...
Method #1 ran about as fast as Method #2
Both Method #1 and Method #2 ran faster than DaveRandom's method.
Again, I'll state that fabricated tests for micro-optimization may be pointless and real tests should be done on your REAL data IF it is actually important. If you merely prefer the logical flow of another answer on this page, I totally respect that.

Traversing all values of an array of arrays

N in this question means any arbitrary number of any size and is not necessarily (but could be) the same. I have an array with N number of key => value pairs. These key => value pairs can also contain another array of size N with N number of key => value pairs. This array can be of N depth, meaning any key => value pair in the array could map to another array.How do I get all the values of this array (storing them in a new, 1 dimensional array), ignoring the keys in the key => value pairs?
array-walk-recursive
rob at yurkowski dot net 26-Oct-2010
06:16
If you don't really particularly
care about the keys of an array, you
can capture all values quite simply:
$sample = array(
'dog' => 'woof',
'cat' => array(
'angry' => 'hiss',
'happy' => 'purr'
),
'aardvark' => 'kssksskss'
);
$output = array();
// Push all $val onto $output.
array_walk_recursive($sample, create_function('$val, $key, $obj', 'array_push($obj, $val);'), &$output);
// Printing echo nl2br(print_r($output, true));
/*
* Array
* (
* [0] => woof
* [1] => hiss
* [2] => purr
* [3] => kssksskss
* )
*/
You could do smt like this:
$output = array();
function genArray( $arr ) {
global $output;
foreach( $arr as $key => $val ) {
if( is_array($val) )
genArray( $val );
else
output[$key] = $val;
}
}
genArray( $myArray );
Instead of recursion, using global variable and function, it could be done via loops, but this is just a general idea, and probably needs a little of your attention, anyway. That should be a good thing :)
There are a ton of solutions in the comments of the array_values php doc.
http://www.php.net/manual/en/function.array-values.php

Categories