Create nested array by array of keys - php

I've some difficulties creating a nested array by array of keys and assigning a value for the last nested item.
For example, lets $value = 4; and $keys = ['a', 'b', 'c'];
The final result should be:
[
'a' => [
'b' => [
'c' => 4
]
]
]
I've tried with a recursion, but without success.
Any help would be greatly appreciated.

you don't need recursion, just do it from the right to left:
$a = $value;
for ($i = count($keys)-1; $i>=0; $i--) {
$a = array($keys[$i] => $a);
}
or the even shorter version from #felipsmartins:
$a = $value;
foreach (array_reverse($keys) as $valueAsKey) $a = [$valueAsKey => $a];

Your can try it.
$value = 4;
$keys = ['a', 'b', 'c'];
$a = $value;
$i=count($keys)-1;
foreach($keys as $key){
$a = array($keys[$i] => $a);
$i--;
}
print_r($a);
Output
Array
(
[a] => Array
(
[b] => Array
(
[c] => 4
)
)
)

Solution by getting a nested item in the resulting array by reference:
$value = 4;
$keys = ['a', 'b', 'c'];
$result = [];
$reference = &$result;
foreach($keys as $key) {
if (!array_key_exists($key, $reference)) $reference[$key] = [];
$reference = &$reference[$key];
}
$reference = $value;
print_r($result);

Related

Map array with initial letter in PHP

I wish to group a word list in an array with the initial letter.
function alpha($str) {
$result[substr($str,0,1)] = $str;
return $result;
}
$a = ['abc','cde','frtg','acf'];
$b = array_map('alpha', $a);
print_r($b);
What I need:
Array
(
[a] => abc,acf
[c] => cde
[f] => frtg
)
What I get:
Array
(
[0] => Array
(
[a] => abc
)
[1] => Array
(
[c] => cde
)
[2] => Array
(
[f] => frtg
)
[3] => Array
(
[a] => acf
)
)
How about that :
$answer = [];
$a = ['abc','cde','frtg','acf'];
foreach($a as $word){
$key = substr($word,0,1);
if (isset($answer[$key])){
$answer[$key] .= "," . $word;
} else {
$answer[$key] = $word;
}
}
Just add a variable $c and loop over arrays of array using two foreach and group by alphabet...
function alpha($str) {
$result[substr($str,0,1)] = $str;
return $result;
}
$a = ['abc','cde','frtg','acf'];
$b = array_map('alpha', $a);
#print_r($b);
$c = [];
foreach ($b as $key => $values) {
foreach ($values as $key => $value) {
if(!isset($c[$key])){
$c[$key]=$value;
}else{
$c[$key].= "," . $value;
}
}
}
echo "<PRE>";
print_r($c);
Outupt:
Array
(
[a] => abc,acf
[c] => cde
[f] => frtg
)
The function array_map maps to the original indexes but you want new indexes and an altered array, if there are more values with the same initial character. Therefore array_map don't work for you. You could create your new array this way:
$a = ['abc','cde','frtg','acf'];
$b = Array();
$c = Array();
foreach( $a as $v )
{
// multidimensional array
$b[substr($v,0,1)][] = $v;
// comma separated string
$c[substr($v,0,1)] = (isset($c[substr($v,0,1)])) ?
$c[substr($v,0,1)].",$v" : $v;
}
If the first character can also be multibyte Unicode such as ° or €, mb_substr() must be used! Solution with foreach:
$result = [];
$a = ['abc','€de','frtg','acf'];
foreach($a as $word){
$key = mb_substr($word,0,1);
$result[$key] = array_key_exists($key,$result)
? ($result[$key].",".$word)
: $word
;
}
Solution with array_reduce():
$result = array_reduce($a,function($carry,$item){
$key = mb_substr($item,0,1);
$carry[$key] = array_key_exists($key,$carry) ? ($carry[$key].",".$item) : $item;
return $carry;
},[]);
var_export($result);
Output:
array (
'a' => 'abc,acf',
'€' => '€de',
'f' => 'frtg',
)
I think your intention is to store each word into arrays according to its first letter. In this case, the multidimensional array is the right choice.
$array = ['abc','cde','frtg','acf'];
$new_array = array();
foreach($array as $v){
$letter = substr($v,0,1);
if(!isset($new_array[$letter])) {$new_array[$letter] = array();}
array_push($new_array[$letter], $v);
}
print_r($new_array);

How to modify array with recursion

I have array
$arr = ['one', 'two', 'free'];
$value = 10;
Need use recursion function.
So I wanna get array like this
$result = ['one' => ['two' => ['free' => 10]]];
You can loop the array in reverse and build the array from the furthest nested value and back.
$arr = ['one', 'two', 'free'];
$value = 10;
$arr = array_reverse($arr);
foreach($arr as $key => $val){
if($key==0){
$new[$val]= $value;
}else{
$new = [$val => $new]; //this overwrites the array with a new array with another layer
}
}
var_dump($new);
https://3v4l.org/VRJOY
For fun, here's how to accomplish this with a recursive function:
$array = ['one', 'two', 'three', 'four'];
$val = 10;
function do_array_thing($array, $val)
{
if (count($array) > 0) {
$key = array_pop($array);
return do_array_thing($array, [$key => $val]);
} else {
return $val;
}
}
print_r(do_array_thing($array, $val));
Returns:
Array
(
[one] => Array
(
[two] => Array
(
[three] => Array
(
[four] => 10
)
)
)
)

php how to sort the values in multiple arrays in the order of frequency

I have an array containing multiple arrays like
$A = array();
$A[0] = array("1","2","3","4","5");
$A[1] = array("1","6","7","8");
$A[2] = array("0","1","3");
I want to sort the values in multiple arrays in the order of frequency and put them into another array let's say $B.
The values in $B is "1","1","1","3","3","0","2","4","5","6","7","8".
$A = array();
$A[0] = array("1","2","3","4","5");
$A[1] = array("1","6","7","8");
$A[2] = array("0","1","3");
//Merging above array in to one array
$merged = array_values(call_user_func_array('array_merge', $A));
//Getting occurrence count
$counts = array_count_values($merged);
//Sort by count
arsort($counts);
//Adding to required array
$B = array();
foreach ($counts as $k => $v)
for($i=1;$i<=$v;$i++)
$B[] = $k;
echo "<pre>";
print_r($B);
echo "</pre>";
Result
Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 3
[4] => 3
[5] => 0
[6] => 8
[7] => 7
[8] => 5
[9] => 2
[10] => 4
[11] => 6
)
First merge all arrays
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$resultado = array_merge($array1, $array2);
see -> http://php.net/manual/es/function.array-merge.php
Second sort the big array
arsort($resultado );
see -> http://php.net/manual/es/array.sorting.php
Use a hash table to count the frequency of each number, and then store them in the decreasing order of frequency in array $B, like this:
$hash_table = array();
foreach($A as $array){
foreach($array as $value){
if(empty($hash_table[$value])){
$hash_table[$value] = 1;
}else{
$hash_table[$value] += 1;
}
}
}
arsort($hash_table);
$B = array();
foreach($hash_table as $key => $value){
for($i = 0; $i < $value; ++$i){
$B[] = $key;
}
}
var_dump($B); // to see the contents of array $B
If order of same occurance count items isn't important, you can use:
// Merge all arrays
$counts = array_count_values(call_user_func_array('array_merge', $A));
// Sort by occurance
arsort($counts);
// Add [value] to new array [occurance] times
$B = array();
array_walk($counts, function($occurances, $value) use (&$B){
for($i=0;$i<$occurances;$i++) $B[] = $value;
});
echo implode(',', $B);
Output
1,1,1,3,3,0,8,7,5,2,4,6
Array print in order of count and index:
$temp = array();
foreach($A as $b){
foreach($b as $c){
if(isset($tmep[$c])){
$tmep[$c]++;
}else{
$tmep[$c] = 1;
}
}
}
function SortArrayByKeyThanValue (&$pArray, $pSortMethodForKey = SORT_ASC, $pSortMethodForValue = SORT_DESC){
# check user input: sorting is not necessary
if (count($pArray) < 2)
return;
# define $k and $v as array_multisort() needs real variables, as user input is put by reference
$k = array_keys ($pArray);
$v = array_values($pArray);
array_multisort(
$v, $pSortMethodForValue,
$k, $pSortMethodForKey
);
$pArray = array_combine($k, $v);
}
SortArrayByKeyThanValue($tmep);
$B = array();
array_walk($tmep, function($occurances, $value) use (&$B){
for($i=0;$i<$occurances;$i++) $B[] = $value;
});
echo implode(',', $B);

Trouble finding odd results of an array

I can't seem to find the answer to these problem. I have the following php code.
$r = 1,2,3,4,5,6 and so on
and i want to get the number like this
$result = 1,3,5
or if i have
$s = b,c,d,e,f,g,h,i...and so on
the result should be
$results c,e,g,i
Pretty easy with numbers, the trick with letters is to use ord()
$arr = array(1,2,3,4,5,6);
$arr = array_filter ($arr, function ($number) {
return $number % 2;
});
print_r($arr);
$arr = array('a', 'b', 'c', 'd', 'e');
$arr = array_filter ($arr, function ($letter) {
return ord($letter) % 2;
});
print_r($arr);
Output :
Array (
[0] => 1
[2] => 3
[4] => 5
)
Array (
[0] => a
[2] => c
[4] => e
)
And here is a generic solution, working with both letters and numbers :
$arr = array_filter ($arr, function ($value) {
$value = is_int($value) ? $value : ord($value);
return $value % 2;
});
This will work:
$a = array(1,2,3,4,5,6);
foreach($a as $k => $v){
if($k&1){
unset($a[$k]);
}
}
print_r($a);

PHP convert one dimensional array into multidimensional

I have one array as
$tmpArr = array('A', 'B', 'C');
I want to process this array and want new array as
$tmpArr[A][B][C] = C
I.e last element becomes the value of final array.
Can anyone suggest the solution? Please help. Thanks in advance
Iterate the array of keys and use a reference for the end of the chain:
$arr = array();
$ref = &$arr;
foreach ($tmpArr as $key) {
$ref[$key] = array();
$ref = &$ref[$key];
}
$ref = $key;
$tmpArr = $arr;
$tmpArr = array('A', 'B', 'C');
$array = array();
foreach (array_reverse($tmpArr) as $arr)
$array = array($arr => $array);
Output:
Array
(
[A] => Array
(
[B] => Array
(
[C] => Array
(
)
)
)
)
$tmpArr[$tmpArr[0]][$tmpArr[1]][$tmpArr[2]] = $tmpArr[2];
Is that what you want?

Categories