I have an code from database like
$exp = ukuran:33,34,35;warna:putih,hitam;
i want to make an array like
$ukuran = array("33", "34", "35");
$warna = array("putih","hitam");
i have try to use explode but i have trouble result.
explode(";",$exp);
the result like
Array
(
[0] => ukuran:33,34,35
[1] => warna:putih,hitam
[2] =>
)
Anyone can help me, how to explode this case please?
$string = 'ukuran:33,34,35;warna:putih,hitam;';
$string = str_replace(['ukuran:', 'warna:'], '', $string);
$exploded = explode(';', $string);
$ukuran = explode(',', $exploded[0]);
$warna = explode(',', $exploded[1]);
If you want to do it dynamically you can't create variables but you can create an array with the types as keys:
$string = 'ukuran:33,34,35;warna:putih,hitam;';
$exploded = explode(';', $string);
$keysAndValues = [];
foreach($exploded as $exp) {
if (strlen($exp) > 0) {
$key = substr($exp, 0, strpos($exp, ':' ) );
$values = substr($exp, strpos($exp, ':' ) + 1, strlen($exp) );
$values = explode(',', $values);
$keysAndValues[$key] = $values;
}
}
This will output:
array (size=2)
'ukuran' =>
array (size=3)
0 => string '33' (length=2)
1 => string '34' (length=2)
2 => string '35' (length=2)
'warna' =>
array (size=2)
0 => string 'putih' (length=5)
1 => string 'hitam' (length=5)
Call them like this:
var_dump($keysAndValues['ukuran']);
var_dump($keysAndValues['warna']);
I would personally say continue as you are, then with your array in your result, loop through each item in the array and store it like so
$string = 'ukuran:33,34,35;warna:putih,hitam;';
$exploded = explode(';',$string);
$master = [];
foreach($exploded as $key => $foo){
$namedKey = explode(':',$foo);
$bar = substr($foo, strpos($foo, ":") + 1); //Get everything after the ; character
$master[$namedKey[0]] = explode(",",$bar);
}
This should return a result something along the lines of
array(3) {
["ukuran"]=>
array(3) {
[0]=>
string(2) "33"
[1]=>
string(2) "34"
[2]=>
string(2) "35"
}
["warna"]=>
array(2) {
[0]=>
string(5) "putih"
[1]=>
string(5) "hitam"
}
}
You can use regex to match words and numbers separate.
Then use array_filter to remove the empty values.
$exp = "ukuran:33,34,35;warna:putih,hitam";
Preg_match_all("/(\d+)|([a-zA-Z]+)/", $exp, $matches);
Unset($matches[0]);
$matches[1] = array_filter($matches[1]);
$matches[2] = array_filter($matches[2]);
Var_dump($matches);
https://3v4l.org/cREn7
Actually there are many ways to do what you want, But If I were you then I'll try this way :)
<?php
$exp = 'ukuran:33,34,35;warna:putih,hitam';
$result = explode(';',$exp);
foreach($result as $k=>$v){
$key_value = explode(':',$v);
// this line will help your to treat your $ukuran and $warna as array variable
${$key_value[0]} = explode(',',$key_value[1]);
}
print '<pre>';
print_r($ukuran);
print_r($warna);
print '</pre>';
?>
DEMO: https://3v4l.org/BAaCT
I have this kind of array
array(1) {
["key,language,text"] => "home,es,casa"
}
Is it possible to parse it and split it to have
array(3) {
['key'] => "home" ,
['language'] => "es" ,
['text'] => "casa"
}
My actual solution is to do the following but I'm pretty sure that I can find a better approach
$test = explode(',', $my_array['key,language,text']);
$my_array['key'] = $test[0];
$my_array['language'] = $test[1];
$my_array['text'] = $test[2];
You can use array_combine to create an array from an array of keys and values, providing the length of each is equal, it will return false if there is a mismatch.
foreach($array as $keys_str => $values_str) {
$keys = explode(",", $keys_str);
$values = explode(",", $values_str);
$kv_array = array_combine($keys, $values);
}
$kv_array would be in the format you're after.
Give it a try..
$arr = array("key,language,text" => "home,es,casa");
$val = explode(",", $arr[key($arr)]);
foreach(explode(",", key($arr)) as $k => $key){
$data[$key] = $val[$k];
}
If you have an array with only 1 entry:
$a = ["key,language,text" => "home,es,casa"];
you could use reset which will return the value of the first array element and key which will return the key of the array element that's currently being pointed to by the internal pointer.
Then use explode and use a comma as the delimiter and use array_combine using the arrays from explode for the keys and the values to create the result.
$result = array_combine(explode(',', key($a)), explode(',', reset($a)));
print_r($result);
That will give you:
array(3) {
["key"]=>
string(4) "home"
["language"]=>
string(2) "es"
["text"]=>
string(4) "casa"
}
This best solution for you :
//this your problem
$array = [
"key,language,text" => "home,es,casa",
"key,language,text" => "home1,es1,casa1"
];
$colms_tmp = 0;
//this your solution, foreach all
foreach($array as $key => $val){
//split your value
$values = explode(",",$val);
//foreach the key (WITH COLMNS), $colm is number of key after explode
foreach(explode(",",$key) as $colm => $the_key){
$result[$colms_tmp][$the_key] = $values[$colm];
}
$colms_tmp++;
}
i haven't try it, but i think this can help you.
This question already has answers here:
How to Flatten a Multidimensional Array?
(31 answers)
Closed 1 year ago.
It's probably beginner question but I'm going through documentation for longer time already and I can't find any solution. I thought I could use implode for each dimension and then put those strings back together with str_split to make new simple array. However I never know if the join pattern isn't also in values and so after doing str_split my original values could break.
Is there something like combine($array1, $array2) for arrays inside of multi-dimensional array?
$array = your array
$result = call_user_func_array('array_merge', $array);
echo "<pre>";
print_r($result);
REF: http://php.net/manual/en/function.call-user-func-array.php
Here is another solution (works with multi-dimensional array) :
function array_flatten($array) {
$return = array();
foreach ($array as $key => $value) {
if (is_array($value)){ $return = array_merge($return, array_flatten($value));}
else {$return[$key] = $value;}
}
return $return;
}
$array = Your array
$result = array_flatten($array);
echo "<pre>";
print_r($result);
This is a one line, SUPER easy to use:
$result = array();
array_walk_recursive($original_array,function($v) use (&$result){ $result[] = $v; });
It is very easy to understand, inside the anonymous function/closure. $v is the value of your $original_array.
Use array_walk_recursive
<?php
$aNonFlat = array(
1,
2,
array(
3,
4,
5,
array(
6,
7
),
8,
9,
),
10,
11
);
$objTmp = (object) array('aFlat' => array());
array_walk_recursive($aNonFlat, create_function('&$v, $k, &$t', '$t->aFlat[] = $v;'), $objTmp);
var_dump($objTmp->aFlat);
/*
array(11) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
[7]=>
int(8)
[8]=>
int(9)
[9]=>
int(10)
[10]=>
int(11)
}
*/
?>
Tested with PHP 5.5.9-1ubuntu4.24 (cli) (built: Mar 16 2018 12:32:06)
If you specifically have an array of arrays that doesn't go further than one level deep (a use case I find common) you can get away with array_merge and the splat operator.
<?php
$notFlat = [[1,2],[3,4]];
$flat = array_merge(...$notFlat);
var_dump($flat);
Output:
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
The splat operator effectively changes the array of arrays to a list of arrays as arguments for array_merge.
// $array = your multidimensional array
$flat_array = array();
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v){
$flat_array[$k] = $v;
}
Also documented:
http://www.phpro.org/examples/Flatten-Array.html
Sorry for necrobumping, but none of the provided answers did what I intuitively understood as "flattening a multidimensional array". Namely this case:
[
'a' => [
'b' => 'value',
]
]
all of the provided solutions would flatten it into just ['value'], but that loses information about the key and the depth, plus if you have another 'b' key somewhere else, it will overwrite them.
I wanted to get a result like this:
[
'a_b' => 'value',
]
array_walk_recursive doesn't pass the information about the key it's currently recursing, so I did it with just plain recursion:
function flatten($array, $prefix = '') {
$return = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$return = array_merge($return, flatten($value, $prefix . $key . '_'));
} else {
$return[$prefix . $key] = $value;
}
}
return $return;
}
Modify the $prefix and '_' separator to your liking.
Playground here: https://3v4l.org/0B8hf
With PHP 7, you can use generators and generator delegation (yield from) to flatten an array:
function array_flatten_iterator (array $array) {
foreach ($array as $value) {
if (is_array($value)) {
yield from array_flatten_iterator($value);
} else {
yield $value;
}
}
}
function array_flatten (array $array) {
return iterator_to_array(array_flatten_iterator($array), false);
}
Example:
$array = [
1,
2,
[
3,
4,
5,
[
6,
7
],
8,
9,
],
10,
11,
];
var_dump(array_flatten($array));
http://3v4l.org/RU30W
A non-recursive solution (but order-destroying):
function flatten($ar) {
$toflat = array($ar);
$res = array();
while (($r = array_shift($toflat)) !== NULL) {
foreach ($r as $v) {
if (is_array($v)) {
$toflat[] = $v;
} else {
$res[] = $v;
}
}
}
return $res;
}
function flatten_array($array, $preserve_keys = 0, &$out = array()) {
# Flatten a multidimensional array to one dimension, optionally preserving keys.
#
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
foreach($array as $key => $child)
if(is_array($child))
$out = flatten_array($child, $preserve_keys, $out);
elseif($preserve_keys + is_string($key) > 1)
$out[$key] = $child;
else
$out[] = $child;
return $out;
}
Another method from PHP's user comments (simplified) and here:
function array_flatten_recursive($array) {
if (!$array) return false;
$flat = array();
$RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($RII as $value) $flat[] = $value;
return $flat;
}
The big benefit of this method is that it tracks the depth of the recursion, should you need that while flattening.
This will output:
$array = array(
'A' => array('B' => array( 1, 2, 3)),
'C' => array(4, 5)
);
print_r(array_flatten_recursive($array));
#Returns:
Array (
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
In PHP>=5.3 and based on Luc M's answer (the first one) you can make use of closures like this
array_walk_recursive($aNonFlat, function(&$v, $k, &$t){$t->aFlat[] = $v;}, $objTmp);
I love this because I don't have to surround the function's code with quotes like when using create_function()
Using higher-order functions (note: I'm using inline anonymous functions, which appeared in PHP 5.3):
function array_flatten($array) {
return array_reduce(
$array,
function($prev, $element) {
if (!is_array($element))
$prev[] = $element;
else
$prev = array_merge($prev, array_flatten($element));
return $prev;
},
array()
);
}
I found a simple way to convert multilevel array into one.
I use the function "http_build_query" which converts the array into a url string.
Then, split the string with explode and decode the value.
Here is a sample.
$converted = http_build_query($data);
$rows = explode('&', $converted);
$output = array();
foreach($rows AS $k => $v){
list($kk, $vv) = explode('=', $v);
$output[ urldecode($kk) ] = urldecode($vv);
}
return $output;
A new approach based on the previous example function submited by chaos, which fixes the bug of overwritting string keys in multiarrays:
# Flatten a multidimensional array to one dimension, optionally preserving keys.
# $array - the array to flatten
# $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys
# $out - internal use argument for recursion
function flatten_array($array, $preserve_keys = 2, &$out = array(), &$last_subarray_found)
{
foreach($array as $key => $child)
{
if(is_array($child))
{
$last_subarray_found = $key;
$out = flatten_array($child, $preserve_keys, $out, $last_subarray_found);
}
elseif($preserve_keys + is_string($key) > 1)
{
if ($last_subarray_found)
{
$sfinal_key_value = $last_subarray_found . "_" . $key;
}
else
{
$sfinal_key_value = $key;
}
$out[$sfinal_key_value] = $child;
}
else
{
$out[] = $child;
}
}
return $out;
}
Example:
$newarraytest = array();
$last_subarray_found = "";
$this->flatten_array($array, 2, $newarraytest, $last_subarray_found);
/*consider $mArray as multidimensional array and $sArray as single dimensional array
this code will ignore the parent array
*/
function flatten_array2($mArray) {
$sArray = array();
foreach ($mArray as $row) {
if ( !(is_array($row)) ) {
if($sArray[] = $row){
}
} else {
$sArray = array_merge($sArray,flatten_array2($row));
}
}
return $sArray;
}
you can try this:
function flat_an_array($a)
{
foreach($a as $i)
{
if(is_array($i))
{
if($na) $na = array_merge($na,flat_an_array($i));
else $na = flat_an_array($i);
}
else $na[] = $i;
}
return $na;
}
If you're okay with loosing array keys, you may flatten a multi-dimensional array using a recursive closure as a callback that utilizes array_values(), making sure that this callback is a parameter for array_walk(), as follows.
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = null;
$callback = function ( $item ) use(&$callback, &$nu_array) {
if (!is_array($item)) {
$nu_array[] = $item;
}
else
if ( is_array( $item ) ) {
foreach( array_values($item) as $v) {
if ( !(is_array($v))) {
$nu_array[] = $v;
}
else
{
$callback( $v );
continue;
}
}
}
};
array_walk($array, $callback);
print_r($nu_array);
The one drawback of the preceding example is that it involves writing far more code than the following solution which uses array_walk_recursive() along with a simplified callback:
<?php
$array = [1,2,3,[5,6,7]];
$nu_array = [];
array_walk_recursive($array, function ( $item ) use(&$nu_array )
{
$nu_array[] = $item;
}
);
print_r($nu_array);
See live code
This example seems preferable to the previous one, hiding the details about how values are extracted from a multidimensional array. Surely, iteration occurs, but whether it entails recursion or control structure(s), you'll only know from perusing array.c. Since functional programming focuses on input and output rather than the minutiae of obtaining a result, surely one can remain unconcerned about how behind-the-scenes iteration occurs, that is until a perspective employer poses such a question.
You can use the flatten function from Non-standard PHP library (NSPL). It works with arrays and any iterable data structures.
assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]]));
Simple approach..See it via recursion..
<?php
function flatten_array($simple){
static $outputs=array();
foreach ( $simple as $value)
{
if(is_array($value)){
flatten_array($value);
}
else{
$outputs[]=$value;
}
}
return $outputs;
}
$eg=['s'=>['p','n'=>['t']]];
$out=flatten_array($eg);
print_r($out);
?>
Someone might find this useful, I had a problem flattening array at some dimension, I would call it last dimension so for example, if I have array like:
array (
'germany' =>
array (
'cars' =>
array (
'bmw' =>
array (
0 => 'm4',
1 => 'x3',
2 => 'x8',
),
),
),
'france' =>
array (
'cars' =>
array (
'peugeot' =>
array (
0 => '206',
1 => '3008',
2 => '5008',
),
),
),
)
Or:
array (
'earth' =>
array (
'germany' =>
array (
'cars' =>
array (
'bmw' =>
array (
0 => 'm4',
1 => 'x3',
2 => 'x8',
),
),
),
),
'mars' =>
array (
'france' =>
array (
'cars' =>
array (
'peugeot' =>
array (
0 => '206',
1 => '3008',
2 => '5008',
),
),
),
),
)
For both of these arrays when I call method below I get result:
array (
0 =>
array (
0 => 'm4',
1 => 'x3',
2 => 'x8',
),
1 =>
array (
0 => '206',
1 => '3008',
2 => '5008',
),
)
So I am flattening to last array dimension which should stay the same, method below could be refactored to actually stop at any kind of level:
function flattenAggregatedArray($aggregatedArray) {
$final = $lvls = [];
$counter = 1;
$lvls[$counter] = $aggregatedArray;
$elem = current($aggregatedArray);
while ($elem){
while(is_array($elem)){
$counter++;
$lvls[$counter] = $elem;
$elem = current($elem);
}
$final[] = $lvls[$counter];
$elem = next($lvls[--$counter]);
while ( $elem == null){
if (isset($lvls[$counter-1])){
$elem = next($lvls[--$counter]);
}
else{
return $final;
}
}
}
}
If you're interested in just the values for one particular key, you might find this approach useful:
function valuelist($array, $array_column) {
$return = array();
foreach($array AS $row){
$return[]=$row[$array_column];
};
return $return;
};
Example:
Given $get_role_action=
array(3) {
[0]=>
array(2) {
["ACTION_CD"]=>
string(12) "ADD_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
[1]=>
array(2) {
["ACTION_CD"]=>
string(13) "LINK_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
[2]=>
array(2) {
["ACTION_CD"]=>
string(15) "UNLINK_DOCUMENT"
["ACTION_REASON"]=>
NULL
}
}
than $variables['role_action_list']=valuelist($get_role_action, 'ACTION_CD'); would result in:
$variables["role_action_list"]=>
array(3) {
[0]=>
string(12) "ADD_DOCUMENT"
[1]=>
string(13) "LINK_DOCUMENT"
[2]=>
string(15) "UNLINK_DOCUMENT"
}
From there you can perform value look-ups like so:
if( in_array('ADD_DOCUMENT', $variables['role_action_list']) ){
//do something
};
any of this didnt work for me ...
so had to run it myself.
works just fine:
function arrayFlat($arr){
$out = '';
foreach($arr as $key => $value){
if(!is_array($value)){
$out .= $value.',';
}else{
$out .= $key.',';
$out .= arrayFlat($value);
}
}
return trim($out,',');
}
$result = explode(',',arrayFlat($yourArray));
echo '<pre>';
print_r($result);
echo '</pre>';
Given multi-dimensional array and converting it into one-dimensional, can be done by unsetting all values which are having arrays and saving them into first dimension, for example:
function _flatten_array($arr) {
while ($arr) {
list($key, $value) = each($arr);
is_array($value) ? $arr = $value : $out[$key] = $value;
unset($arr[$key]);
}
return (array)$out;
}