Is it possible, in PHP, to flatten a (bi/multi)dimensional array without using recursion or references?
I'm only interested in the values so the keys can be ignored, I'm thinking in the lines of array_map()
and array_values()
.
Is it possible, in PHP, to flatten a (bi/multi)dimensional array without using recursion or references?
I'm only interested in the values so the keys can be ignored, I'm thinking in the lines of array_map()
and array_values()
.
Thanks for all the given answers.
I have transformed it in the following, which is an improved version. It eliminates the need of a root prefix, does not need to use references, it is cleaner to read, and it has a better name:
function array_flat($array, $prefix = '')
{
$result = array();
foreach ($array as $key => $value)
{
$new_key = $prefix . (empty($prefix) ? '' : '.') . $key;
if (is_array($value))
{
$result = array_merge($result, array_flat($value, $new_key));
}
else
{
$result[$new_key] = $value;
}
}
return $result;
}
The variadiac php5.6+ version: (Offers the added benefits of not breaking on missing values and inserting null
where values are missing.)
Code: (Demo)
var_export(array_map(function(){return implode(',',func_get_args());},...$text));
The non-variadic version:
Code: (Demo)
foreach($text as $i=>$v){
$result[]=implode(',',array_column($text,$i));
}
var_export($result);
Input:
$text = [
['001','002','003'],
['America','Japan','South Korea'],
['Washington DC','Tokyo','Seoul']
];
Output from either method:
array (
0 => '001,America,Washington DC',
1 => '002,Japan,Tokyo',
2 => '003,South Korea,Seoul',
)
Nearly exact duplicate page: Combining array inside multidimensional array with same key
Using List::Flatten
seems like the easiest:
use List::Flatten;
my @foo = (1, 2, [3, 4, 5], 6, [7, 8], 9);
my @bar = flat @foo; # @bar contains 9 elements, same as (1 .. 9)
Actually, that module exports a single simple function flat
, so you might as well copy the source code:
sub flat(@) {
return map { ref eq 'ARRAY' ? @$_ : $_ } @_;
}
You could also make it recursive to support more than one level of flattening:
sub flat { # no prototype for this one to avoid warnings
return map { ref eq 'ARRAY' ? flat(@$_) : $_ } @_;
}
You can do it like this, do the calculation from the innermost of the array. Check the demo.
<?php
function f(&$array)
{
foreach($array as $k => &$v)
{
if(is_array($v))
{
if(count($v) == count($v, 1))
{
unset($array[$k]);
if($k == 'sum')
{
$v = array_sum($v);
$array[] = $v;
}elseif($k == 'multiply'){
$v = array_product($v);
$array[] = $v;
}else{
foreach($v as $vv)
$array[] = $vv;
}
}else
f($v);
}
}
}
while(count($array) != count($array, 1))
{
f($array);
}
print_r($array);
Note:
traverse array from outer to inner
traverse array from inner to outer
You can use the Standard PHP Library (SPL) to "hide" the recursion.
prints