I have an array like this:
<?php
$array = array( 0 => 'foo', 1 => 'bar', ..., x => 'foobar' );
?>
What is the fastest way to create a multidimensional array out of this, where every value is another level?
So I get:
array (size=1)
'foo' =>
array (size=1)
'bar' =>
...
array (size=1)
'x' =>
array (size=1)
0 => string 'foobar' (length=6)
<?php
$i = count($array)-1;
$lasta = array($array[$i]);
$i--;
while ($i>=0)
{
$a = array();
$a[$array[$i]] = $lasta;
$lasta = $a;
$i--;
}
?>
$a is the output.
What exactly are you trying to do? So many arrays of size 1 seems a bit silly.
you probably want to use foreach loop(s) with a key=>value pair
foreach ($array as $k=>$v) {
print "key: $k value: $v";
}
You could do something like this to achieve the array you asked for:
$newArray = array();
for ($i=count($array)-1; $i>=0; $i--) {
$newArray = array($newArray[$i]=>$newArray);
}
I'm confused about what you want to do with non-numeric keys (ie, x in your example). But in any case using array references will help
$array = array( 0 => 'foo', 1 => 'bar', x => 'foobar' );
$out = array();
$curr = &$out;
foreach ($array as $key => $value) {
$curr[$value] = array();
$curr = &$curr[$value];
}
print( "In: \n" );
print_r($array);
print( "Out : \n" );
print_r($out);
Prints out
In:
Array
(
[0] => foo
[1] => bar
[x] => foobar
)
Out :
Array
(
[foo] => Array
(
[bar] => Array
(
[foobar] => Array
(
)
)
)
)
You can use a recursive function so that you're not iterating through the array each step. Here's such a function I wrote.
function expand_arr($arr)
{
if (empty($arr))
return array();
return array(
array_shift($arr) => expand_arr($arr)
);
}
Your question is a little unclear since in your initial statement you're using the next value in the array as the next step down's key and then at the end of your example you're using the original key as the only key in the next step's key.
Related
I have a two array first is:
$array1 = ['settings:rules:key','settings:scrum:way:other'];
I have explode $array1:
$temp_array = explode(":",$array1);
Now I have another array:
$array2 = [settings] => Array
( [rules] => Array
(
[0] => Array
(
[key] =>
[showValueField] => 1
)
)
something like this.
I need to access second array with key given in first array like:
$array2['settings']['rules']['key']
I have to get this keys from first array after explode
You can do it with this kind of loop:
function getVal($path, $arr) {
$current = $arr[array_shift($path)];
while (count($path)) {
$key = array_shift($path);
if (!is_array($current) || !isset($current[$key]))
return false; // protect against non-existing keys
$current = $current[$key];
}
return $current;
}
//example used:
$arr = array("settings" => array("rules" => array("key" => "AAA")));
echo getVal(explode(":",'settings:rules:key'), $arr) . PHP_EOL;
How should I make this array value that is in string form
Array
(
[0] => ["1","2"]
[1] => ["5"]
)
into int form
Array
(
[0] => 1
[1] => 2
[2] => 5
)
Is it complicated? Anyone can help?
you can use array_map to parse string to int and array_reduce with array_merge to join the arrays
$data = Array(["1","2"],["5"]);
$result = array_map('intval', array_reduce($data, 'array_merge', array()));
print_r($result);
Try this:
$array = [
["1", "2"],
["5"],
];
$newArray = [];
foreach ($array as $rowArr) {
foreach ($rowArr as $str) {
$newArray[] = intval($str);
}
}
var_dump($newArray);
This returns:
array (size=3)
0 => int 1
1 => int 2
2 => int 5
This works by iterating $array, then iterating $array's child elements ($rowArr) and adding each element to $newArray after running intval on it.
Use array_reduce (https://3v4l.org/H4eIV)
$a = Array
(
0=> ["1","2"],
1=> ["5"]
);
$r = array_reduce($a, 'array_merge', array());
var_export($r);
Result:
array (
0 => '1',
1 => '2',
2 => '5',
)
You only need to loop through the two layers of your array.
$input=[["1","2"],["5"]];
foreach($input as $a){
foreach($a as $v){
$result[]=+$v; // make integer
}
}
var_export($result);
Another way: create a closure that casts variables to ints and appends them to an array.
$appendInt = function($x) use (&$result) { $result[] = (int) $x; };
// reference to result array^ append to result^ ^cast to int
Apply it to every element of your multidimensional array with array_walk_recursive.
array_walk_recursive($your_array, $appendInt);
The flat array of ints will be in the $result variable.
I have a problem I cannot fix. I have 2 arrays and a string. The first array contains the keys the second one should use. The first one is like this:
Array
(
[0] => foo
[1] => bar
[2] => hello
)
Now I need a PHP code that converts it to the second array:
Array
(
[foo] => Array
(
[bar] => Array
(
[hello] => MyString
)
)
)
The number of items is variable.
Can someone please tell me how to do this?
You should use references to solve this problem:
$a = array (0 => 'foo', 1 => 'bar', 2 => 'hello' );
$b = array();
$ptr = &$b;
foreach ($a as $val) {
$ptr[$val] = Array();
$ptr = &$ptr[$val];
}
$ptr = 'MyString';
var_dump($b);
All you need is :
$path = array(
0 => 'foo',
1 => 'bar',
2 => 'hello'
);
$data = array();
$t = &$data;
foreach ( $path as $key ) {
$t = &$t[$key];
}
$t = "MyString";
unset($t);
print_r($data);
See Live Demo
Which method is best practice to turn a multidimensional array
Array ( [0] => Array ( [id] => 11 ) [1] => Array ( [id] => 14 ) )
into a simple array? edit: "flattened" array (thanks arxanas for the right word)
Array ( [0] => 11 [1] => 14 )
I saw some examples but is there an easier way besides foreach loops, implode, or big functions? Surely there must a php function that handles this. Or not..?
$array = array();
$newArray = array();
foreach ( $array as $key => $val )
{
$temp = array_values($val);
$newArray[] = $temp[0];
}
See it here in action: http://viper-7.com/sWfSbD
Here you have it in function form:
function array_flatten ( $array )
{
$out = array();
foreach ( $array as $key => $val )
{
$temp = array_values($val);
$out[] = $temp[0];
}
return $out;
}
See it here in action: http://viper-7.com/psvYNO
You could use array_walk_recursive to flatten an array.
$ret = array();
array_walk_recursive($arr, function($var) use (&$ret) {
$ret[] = $var;
});
var_dump($ret);
If you have a multidimensional array that shouldn't be a multidimensional array (has the same keys and values) and it has multiple depths of dimension, you can just use recursion to loop through it and append each item to a new array. Just be sure not to get a headache with it :)
Here's an example. (It's probably not as "elegant" as xdazz", but it's an alternate without using "use" closure.) This is how the array might start out like:
Start
array (size=2)
0 =>
array (size=1)
'woeid' => string '56413072' (length=8)
1 =>
array (size=1)
'woeid' => string '56412936' (length=8)
Then you might want to have something like this:
Target
array (size=2)
0 => string '56413072' (length=8)
1 => string '56412936' (length=8)
You can use array_walk_recursive
Code
$woeid = array();
array_walk_recursive($result['results']['Result'], function ($item, $key, $woeid) {
if ($key == 'woeid') {
$woeid[] = $item;
}
}, &$woeid);
my php array looks like this:
Array (
[0] => dummy
[1] => stdClass Object (
[aid] => 1
[atitle] => Ameya R. Kadam )
[2] => stdClass Object (
[aid] => 2
[atitle] => Amritpal Singh )
[3] => stdClass Object (
[aid] => 3
[atitle] => Anwar Syed )
[4] => stdClass Object (
[aid] => 4
[atitle] => Aratrika )
) )
now i want to echo the values inside [atitle].
to be specific i want to implode values of atitle into another variable.
how can i make it happen?
With PHP 5.3:
$result = array_map(function($element) { return $element->atitle; }, $array);
if you don't have 5.3 you have to make the anonymous function a regular one and provide the name as string.
Above I missed the part about the empty element, using this approach this could be solved using array_filter:
$array = array_filter($array, function($element) { return is_object($element); });
$result = array_map(function($element) { return $element->atitle; }, $array);
If you are crazy you could write this in one line ...
Your array is declared a bit like this :
(Well, you're probably, in your real case, getting your data from a database or something like that -- but this should be ok, here, to test)
$arr = array(
'dummy',
(object)array('aid' => 1, 'atitle' => 'Ameya R. Kadam'),
(object)array('aid' => 2, 'atitle' => 'Amritpal Singh'),
(object)array('aid' => 3, 'atitle' => 'Anwar Syed'),
(object)array('aid' => 4, 'atitle' => 'Aratrika'),
);
Which means you can extract all the titles to an array, looping over your initial array (excluding the first element, and using the atitle property of each object) :
$titles = array();
$num = count($arr);
for ($i=1 ; $i<$num ; $i++) {
$titles[] = $arr[$i]->atitle;
}
var_dump($titles);
This will get you an array like this one :
array
0 => string 'Ameya R. Kadam' (length=14)
1 => string 'Amritpal Singh' (length=14)
2 => string 'Anwar Syed' (length=10)
3 => string 'Aratrika' (length=8)
And you can now implode all this to a string :
echo implode(', ', $titles);
And you'll get :
Ameya R. Kadam, Amritpal Singh, Anwar Syed, Aratrika
foreach($array as $item){
if(is_object($item) && isset($item->atitle)){
echo $item->atitle;
}
}
to get them into an Array you'd just need to do:
$resultArray = array();
foreach($array as $item){
if(is_object($item) && isset($item->atitle)){
$resultArray[] = $item->atitle;
}
}
Then resultArray is an array of all the atitles
Then you can output as you'd wish
$output = implode(', ', $resultArray);
What you have there is an object.
You can access [atitle] via
$array[1]->atitle;
If you want to check for the existence of title before output, you could use:
// generates the title string from all found titles
$str = '';
foreach ($array AS $k => $v) {
if (isset($v->title)) {
$str .= $v->title;
}
}
echo $str;
If you wanted these in an array it's just a quick switch of storage methods:
// generates the title string from all found titles
$arr = array();
foreach ($array AS $k => $v) {
if (isset($v->title)) {
$arr[] = $v->title;
}
}
echo implode(', ', $arr);
stdClass requires you to use the pointer notation -> for referencing whereas arrays require you to reference them by index, i.e. [4]. You can reference these like:
$array[0]
$array[1]->aid
$array[1]->atitle
$array[2]->aid
$array[2]->atitle
// etc, etc.
$yourArray = array(); //array from above
$atitleArray = array();
foreach($yourArray as $obj){
if(is_object($obj)){
$atitleArray[] = $obj->aTitle;
}
}
seeing as how not every element of your array is an object, you'll need to check for that.