PHP how to use recursive array iterator - php

I have a nested array like:
$array = [
'fookey' => [
[1, 2, 3],
[10, 20, 30],
],
'barkey' => [
[a, b, c],
[d, e, f],
]
]
I need to get 'fookey' and 'barkey' as a strings and every child arrays first and second value.
Count of child array may differ, but always have 3 elements.
I'm trying to iterate over that array using RecursiveArrayIterator:
$rii = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($rii as $key => $val) {
var_dump($val);
}
But i'm getting values 12 times and their indexes instead of 4 child arrays and 'fookey' or 'barkey'.
I would appreciate your help!

Not exactly sure what you need, but that is how I interpreted your question.
foreach ($array as $key => $value) {
echo $key;
echo $value[0] . ' - ' . $value[1];
}

This will iterate and keep the first two elements of each child and merge them together.
foreach($array as &$value) {
$value = array_merge(...array_map(fn($arr) => array_slice($arr, 0, 2), $value));
}
results in
Array
(
[fookey] => Array
(
[0] => 1
[1] => 2
[2] => 10
[3] => 20
)
[barkey] => Array
(
[0] => a
[1] => b
[2] => d
[3] => e
)
)

Related

Evenly push values from a flat array into same positioned rows of a 2d array [duplicate]

This question already has answers here:
Push elements from one array into rows of another array (one element per row)
(4 answers)
Closed 5 months ago.
I need to evenly/synchronously push values from my second array into the rows of my first array.
The arrays which have the same size, but with different keys and depths. The first is an array of rows and the second is a flat array.
$array1 = [
12 => [130, 28, 1],
19 => [52, 2, 3],
34 => [85, 10, 5]
]
$array2 = [4, 38, 33]
Preferred result:
[
12 => [130, 28, 1, 4],
19 => [52, 2, 3, 38],
34 => [85, 10, 5, 33]
]
(I would like to keep the same indices of array 1, however it is not mandatory.)
I have tried these methods, but none of them work because the first array keys are unpredictable.
$final = [];
foreach ($array1 as $idx => $val) {
$final = [$val, $array2[$idx]];
}
Another:
foreach ($array1 as $index => $subArray) {
$array1 [$index][] = $array2[$index];
}
Here is one way to do this:
$merged = array_map('array_merge', $array1, array_chunk($array2, 1));
$result = array_combine(array_keys($array1), $merged);
The second step with array_combine is necessary to reapply the non-sequential keys because array_map won't preserve them in the first step.
An example using foreach
<?php
$a = [
2 => [130, 28, 1, 1, 6],
3 => [52, 2, 3, 3, 27]
];
$b = [5, 38];
$output = [];
$idx = 0;
foreach ($a as $key => $value) {
$value[] = $b[$idx];
$output[$key] = $value;
++$idx;
}
print_r($output);
Sandbox HERE
You can loop $array1 using a foreach to get the current key $index
Get the value from $array2 by using a counter as the array key which, is incremented by 1 for every iteration.
Then add the value to the end of the current array.
$array1 = [
2 => [130, 28, 1, 1, 6],
3 => [52, 2, 3, 3, 27],
13 => [41, 20, 27, 13, 37]
];
$array2 = [89, 99, 109];
$counter = 0;
foreach ($array1 as $index => $subArray) {
$array1[$index][] = $array2[$counter++];
}
print_r($array1);
Output
Array
(
[2] => Array
(
[0] => 130
[1] => 28
[2] => 1
[3] => 1
[4] => 6
[5] => 89
)
[3] => Array
(
[0] => 52
[1] => 2
[2] => 3
[3] => 3
[4] => 27
[5] => 99
)
[13] => Array
(
[0] => 41
[1] => 20
[2] => 27
[3] => 13
[4] => 37
[5] => 109
)
)
See a PHP demo.
Maintaining a counter while iterating is a simple way of accessing second array values while iterating the first. It is not necessary to make multiple passes of the arrays, just one iteration is all that is required.
Codes: (Demos)
a mapper:
$i = -1;
var_export(
array_map(fn($row) => array_merge($row, [$array2[++$i]]), $array1)
);
a looper:
$i = -1;
foreach ($array1 as &$row) {
array_push($row, $array2[++$i]);
}
var_export($array1);
a walker:
$i = -1;
array_walk($array1, fn(&$row, $k) => array_push($row, $array2[++$i]));
var_export($array1);
If you don't care about preserving the first array's keys in the result array, then you can simply use:
var_export(
array_map('array_merge', $array1, array_chunk($array2, 1))
);

PHP array_merge_recursive using foreach loop

I want to merge a few array into a new array, but group them by the same key value
When I use this loop
foreach($mrh as $group){
print_r($group);
};
Out put is
Array (
[2] => 4
)
Array (
[2] => 5
)
Array (
[3] => 7
)
Array (
[3] => 8
)
Array (
[3] => 10
)
My desired output is
array (
[2] => array(
[0] => 4,
[1] => 5
),
[3] => array(
[0] => 7,
[1] => 8,
[2] => 10,
)
)
array_merge_recursive() may be useful, but i cant solve it with an foreach loop
Simply loop the array, and with an inner loop, process the inner elements. Then assign them into the resulting array based on their key.
$result = [];
foreach ($mrh as $group) {
foreach ($group as $key=>$value) {
// Declare the array if it does not exist, to avoid notices
if (!isset($result[$key]))
$result[$key] = [];
// Append the value
$result[$key][] = $value;
}
}
Live demo at https://3v4l.org/NeECu
If your inner array is always on size 1 you can use array-key-first as:
foreach($mrh as $e) {
$k = array_key_first($e);
$res[$k][] = $e[$k];
}
Live example: 3v4l
$mrh = [ [2=>4], [2=>5], [3=>7], [3=>8], [3=>10] ];
$newArray = [];
foreach($mrh as $group){ // loop over groups
foreach($group as $key => $value) { // “loop over” group, to get access to key and value
$newArray[$key][] = $value; // add value as a new element in the sub-array accessed by $key
}
}
using foreach
$a = [
[2 => 4],
[2 => 5],
[3 => 7],
[3 => 8],
[3 => 10]
];
$r = [];
foreach($a as $k => $v){
$_value = end($v);
$r[key($v)][] = $_value;
}
echo '<pre>';
print_r($r);

Sum like values in Multi-Dimensional array php

I need to sum the values in element 1 of my array where the values in element 0 are duplicate.
Here's a small piece of my array
Array
(
[0] => 3
[1] => 1
)
Array
(
[0] => 3
[1] => 2
)
Array
(
[0] => 3
[1] => 128
)
Array
(
[0] => 39
[1] => 4
)
The results i'm expecting to see
Array
(
[0] => 3
[1] => 131
)
Array
(
[0] => 39
[1] => 4
)
I'm still really new to PHP so any help is greatly appreciated.
You can use a combination of array_intersect, array_column and array_sum to only iterate twice. (One for each unique column 0 value).
$col0 = array_column($arr, 0);
$col1 = array_column($arr, 1);
Foreach(array_unique($col0) as $val){
$res[] = [$val, array_sum(array_intersect_key($col1, array_intersect($col0,[$val])))];
}
Var_dump($res);
https://3v4l.org/gKb5b
The way I've done it is made sure all duplicates where put in the same array.
// Your data
$sample = [[3, 1],[3, 2],[3, 128],[39, 4]];
foreach($sample as $array){
$tmp[$array[0]][] = $array[1];
}
# Output: {"3":[1,2,128],"39":[4]}
Now sum the arrays, and put it back to the structure it originally was.
foreach($tmp as $k => $v){
$new[] = [$k, array_sum($v)];
}
# Output: [[3,131],[39,4]]
But many roads lead to Rome.
Try this code. It may help you.
$array = array(["0" => 3, "1" => 1] , ["0" => 3, "1" => 2], ["0" => 3, "1" => 128], ["0" => 39, "1" => 4]);
$finalArray = [];
foreach($array as $a) {
$finalArray[$a[0]][0] = $a[0];
$finalArray[$a[0]][1] = !isset($finalArray[$a[0]][1]) ? $a[1] : $finalArray[$a[0]][1] + $a[1];
}
echo '<pre>';
print_r($finalArray);
exit;
You could do something like this. I have separated into two foreach. Hope it helps.
<?php
$a = [[3,1],[3,2],[3,128],[39,4]];
$result=[];
$temp = [];
foreach($a as $line) {
$temp[$line[0]] += $line[1];
}
foreach($temp as $k => $value) {
$result[]=[$k ,$value];
}
$data =
[
[3,1],
[3,2],
[3,128],
[39,4]
];
foreach($data as $item)
$sums[$item[0]] = ($sums[$item[0]] ?? 0) + $item[1];
$result = array_map(null, array_keys($sums), $sums);
var_export($result);
Output:
array (
0 =>
array (
0 => 3,
1 => 131,
),
1 =>
array (
0 => 39,
1 => 4,
),
)
$arr = [ [ 3, 1],[ 3, 2 ],[ 3, 128], [ 39, 4]];
$sum = [];
foreach($arr as $value) {
$sum[$value[0]][] = $value[1];
}
foreach($sum as $key=>$value ) {
$result[] = [ $key, array_sum($value)];
}
Output:
Array
(
[0] => Array
(
[0] => 3
[1] => 131
)
[1] => Array
(
[0] => 39
[1] => 4
)
)

php: How to foreach a multidimensional array?

I have been trying for a while but I can't seem to loop through a multi dimensional array.
I have this array:
$Work["work_time"] = array();
$Work["break_time"] = array();
$Work["meeting_time"] = array();
$Work["login_time"] = array();
$Work["logout_time"] = array();
$Work["work_date"] = array();
Which print_r($Work) outputs this
Array
(
[work_time] => Array
(
[0] => 0.00
[1] => 3.96
[2] => 7.75
)
[break_time] => Array
(
[0] => 0.00
[1] => 0.00
[2] => 1.06
)
[meeting_time] => Array
(
[0] => 0.00
[1] => 0.00
[2] => 0.00
)
[login_time] => Array
(
[0] => 10:11
[1] => 08:48
[2] => 09:09
)
[logout_time] => Array
(
[0] => 00:00
[1] => 13:00
[2] => 17:59
)
[work_date] => Array
(
[0] => 2018-04-13
[1] => 2018-04-16
[2] => 2018-04-17
)
)
And then I tried to use a foreach loop to loop through it and get the values but it returns nothing..
foreach ($Work as $row) {
echo $row["login_time"];
}
What am I missing?
The array you're trying to iterate with your foreach loop is not the same as the array you have. In order to use that loop, your array would need to be like this instead:
[
[
'work_time' => 0.00,
'break_time' => 0.00,
'meeting_time' => 0.00,
'login_time' => '10:11',
'logout_time' => '00:00',
'work_date' => '2018-04-13'
],
[
'work_time' => 3.96,
'break_time' => 0.00,
'meeting_time' => 0.00,
'login_time' => '08:48',
'logout_time' => '13:00',
'work_date' => '2018-04-16'
],
[
'work_time' => 7.75,
'break_time' => 1.06,
'meeting_time' => 0.00,
'login_time' => '09:09',
'logout_time' => '17:59',
'work_date' => '2018-04-17'
],
];
The array you have looks like the type of input you get if you have an HTML form with multiple rows of inputs with names like this:
<input type="text" name="work[work_time][]">
If that is the case, you can get an array like the one I showed above instead by switching the keys around and specifying a numeric key for each row:
<input type="text" name="work[0][work_time]">
Then it will make more sense to access the data as rows. If that's not the case, well, never mind. :)
On the other hand, with the array you have, you can just iterate one of the inner arrays directly. For example, if you wanted to show login_time values, it's just
foreach ($Work['login_time'] as $login_time) {
echo $login_time;
}
If you need to get corresponding values from the other inner arrays, you can use the key from the array you're iterating to access those as well:
foreach ($Work['login_time'] as $key => $login_time) {
echo 'login time: ' . $login_time . ', work_date: ' . $Work['work_date'][$key];
}
If you really dont know how many dimensions you are dealing with, a recursive solution is what you need.
Here is my code:
$Work["work_time"] = array(1, 2, 3);
$Work["break_time"] = array(4, 5, 6);
$Work["meeting_time"] = array(7, 8, 9);
$Work["login_time"] = array(10, 11, 12);
$Work["logout_time"] = array(13, 14, 15);
$Work["work_date"] = array(16, 17, 18);
function forLoop($array){
foreach ($array as $row) {
if(is_array($row)){
forLoop($row);
}
else{
echo $row;
echo " ";
}
}
}
forLoop($Work);
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
You actually need to make a formating or something to make it work the way you want it to.
Edit: forLoop function calls it's self so it will work on any dimension array. Tell me what you think!
If you already know the key you need (login_time), you do not need to iterate the array. You can access it directly as $Work["login_time"].
If you want to iterate $Work["login_time"], you can use foreach:
foreach ($Work['login_time'] as $row) {
echo $row;
}
Probably need multiple for loops
foreach ($Work as $row) {
foreach($row as $key => $rs) {
echo $rs;
}
}
To loop completely you would need a 2nd foreach inside the first foreach. Like This:
foreach ($Work as $row) {
foreach ($row as $key => $value) {
echo "$key - $value";
}
}
foreach ($dataArray as $innerArray){
foreach ($innerArray as $key=>$value){
// here is where you access the array -- $value
}
}

Sum every last value with all previous values in array

I have an array of some values which I need to convert to new array and sum every value with all previous values. For example (array length, keys and values always differ), this is what I have:
Array
(
[0] => 1
[1] => 1
[2] => 5
[3] => 1
[4] => 1
[7] => 1
[8] => 3
[9] => 1
)
and this is what I need:
Array
(
[0] => 1
[1] => 2
[2] => 7
[3] => 8
[4] => 9
[7] => 10
[8] => 13
[9] => 14
)
I tried many different ways but always stuck at something or realized that I'm wrong somewhere. I have a feeling that I'm trying to reinvent a wheel here, because I think there have to be some simple function for this, but had no luck with finding solution. This is last way I tried:
$array = array( "0"=> 1, "1"=> 1, "2"=> 5, "3"=> 1, "4"=> 1, "7"=> 1, "8"=> 3, "9"=> 1 );
$this = current($array);
$next = next($array);
$end = next(end($array));
$sum = 0;
$newArray = array();
foreach ($array as $val){
if($val != $end){
$sum = ($this += $next);
array_push($newArray, $sum);
}
}
print_r($newArray);
..unfortunately wrong again. I spend lot of time finding ways how not to get where I need to be, can someone kick me into right direction, please?
Suggest you to use array_slice() & array_sum()
$array = array( "0"=>1,"1"=>1,"2"=>5,"3"=>1,"4"=>1,"7"=>1,"8"=>3,"9"=>1);
$keys = array_keys($array);
$array = array_values($array);
$newArr = array();
foreach ($array as $key=>$val) {
$newArr[] = array_sum(array_slice($array, 0, $key+1));
}
$newArr = array_combine($keys, $newArr);
print '<pre>';
print_r($newArr);
print '</pre>';
Output:
Array
(
[0] => 1
[1] => 2
[2] => 7
[3] => 8
[4] => 9
[7] => 10
[8] => 13
[9] => 14
)
Reference:
array_slice()
array_sum()
array_combine()
array_keys()
let assume your array variable is $a;
You can use simple for loop
for($i=1;$i<sizeof($a);$i++)
{
$a[$i]=$a[$i]+$a[$i-1];
}
You can just go over the array sum and add to a new array (in a simple way):
$array = array( "0"=> 1, "1"=> 1, "2"=> 5, "3"=> 1, "4"=> 1, "7"=> 1, "8"=> 3, "9"=> 1 );
var_dump($array);
$newArray = array();
$sum = 0;
foreach ($array as $a){
$sum += $a;
$newArray[]=$sum;
}
var_dump($newArray);
$sums = array_reduce($array, function (array $sums, $num) {
return array_merge($sums, [end($sums) + $num]);
}, []);
In other words, this iterates over the array (array_reduce) and in each iteration appends (array_merge) a number to a new array ($sums) which is the sum of the previous item in the array (end($sums)) and the current number. Uses PHP 5.4+ array syntax ([]).
You complicated too much. Loop trough all elements of array and add current element to sum. Then assign that sum to new array.
$array = array( "0"=> 1, "1"=> 1, "2"=> 5, "3"=> 1, "4"=> 1, "7"=> 1, "8"=> 3, "9"=> 1 );
$sum = 0;
$newArray = array();
foreach ($array as $key=>$val){
$sum += $val;
$newArray[$key]=$sum;
}
Make sure to get indexes right.

Categories