Recursive count elements of multidimensional array [duplicate] - php

This question already has answers here:
Php recursive array counting
(7 answers)
Closed 4 months ago.
I try to make recursive function to count elements on array "levels". But can't do that for two hours already. Check example array:
Array (
[0] => Array (
[0] => Array (
[0] => Array ( )
[1] => Array ( )
)
[1] => Array ( )
)
[1] => Array (
[0] => Array (
[0] => Array (
[0] => Array ( )
[1] => Array ( )
)
)
)
)
The resulting array that count elements on different levels will be:
Array ([0] => 2, [1] => 3, [2] => 3, [3] => 2)
I made function for count total array elements, but no idea how to count each "level"
function countTotalArr($arr, $lvl) {
if ($lvl != 0) $cnt = 1;
else $cnt = 0; // don't count zero level
for ($i = 0; $i < count($arr); $i++)
$cnt += countArr($arr[$i], $lvl + 1);
return $cnt;
}
$total = countTotalArr($referralsCount, 0);

Another solution using while:
// $array is your array at the beginning of iteration
$depthMap = [];
$currentDepth = 0;
while(true) {
$depthMap[$currentDepth] = count($array);
$carry = [];
foreach($array as $item) {
if(is_array($item)) {
$carry = array_merge($carry, $item);
}
}
if(count($carry) < 1) {
break;
}
$array = $carry;
$currentDepth++;
}

Try this code:
<?php
$array = Array (
0 => Array (
0 => Array (
0 => Array ( ) ,
1 => Array ( ) ,
) ,
1 => Array ( ) ,
) ,
1 => Array (
0 => Array (
0 => Array (
0 => Array ( ),
1 => Array ( ),
),
),
) ,
);
function countTotalArr($arr, $lvl)
{
$result = array();
$countOnLevel = count($arr);
$result[$lvl] = $countOnLevel;
$tempArray = array();
foreach($arr as $index => $singleArray)
{
foreach($singleArray as $singleSubArray)
if(is_array($singleSubArray))
$tempArray[] = $singleSubArray;
}
if(!empty($tempArray))
{
$levelTemp = $lvl + 1;
$result = array_merge($result, countTotalArr($tempArray, $levelTemp));
}
return $result;
}
$total = countTotalArr($array, 0);
echo '<pre>';
print_r($total);
Result of print_r($total) is:
Array
(
[0] => 2
[1] => 3
[2] => 3
[3] => 2
)

Related

How do I search for a group of array values and return the array keys for those values?

I have an array with two layers of keys as so:
$array[0][0] = 5;
$array[0][1] = 115;
$array[0][2] = 320;
$array[1][0] = 5;
$array[1][1] = 100;
$array[1][2] = 115;
How can I return the array keys (both of them), based on them having the same value. For example, I want to be able to return [0][0] and [1][0] because they have the same value 5 and then separately return [0][1] and [1][2] because they have the same value 115? I was trying this with the array_keys function, but couldn't really figure it out.
You can do something like:
$array[0][0] = 5;
$array[0][1] = 115;
$array[0][2] = 320;
$array[1][0] = 5;
$array[1][1] = 100;
$array[1][2] = 115;
//Orginize the array
$tempValues = array();
foreach ( $array as $key1 => $value1 ) {
foreach ( $value1 as $key2 => $value2 ) {
if ( !isset( $tempValues[ $value2 ] ) ) $tempValues[ $value2 ] = array();
$tempValues[ $value2 ][] = array( $key1, $key2 );
}
}
//Check which has 2/more
$duplicateValues = array();
foreach ( $tempValues as $key => $tempValue ) {
if ( count( $tempValue ) >= 2 ) $duplicateValues[ $key ] = $tempValue;
}
echo "<pre>";
print_r( $duplicateValues );
echo "</pre>";
This will result to:
Array
(
[5] => Array
(
[0] => Array
(
[0] => 0
[1] => 0
)
[1] => Array
(
[0] => 1
[1] => 0
)
)
[115] => Array
(
[0] => Array
(
[0] => 0
[1] => 1
)
[1] => Array
(
[0] => 1
[1] => 2
)
)
)
There 2 set of pairs
5 - [0][0] and [1][0]
115 - [0][1] and [1][2]

Last value condition foreach in array?

I have an array like that:
[0] => Array
(
[sendby] => 3
[refresh] => 0
[last] => 0
)
[1] => Array
(
[sendby] => 3
[refresh] => 1
[last] => 1
)
[2] => Array
(
[sendby] => 8
[refresh] => 1
[last] => 1
)
I want the value last to be 1 when the value sendby (here 3 and 8) is the last of the entire array! How can I do that?
Get the last 2 value and compare with array [3,8]
// get array of sendby values
$temp = array_column($array, 'sendby');
// get array with two last values
$temp = array_slice($temp, -2);
// Check
if ($temp == [3,8]) {
$value = 1;
}
else {
$value = 0;
}
or in one line
$value = array_slice(array_column($array, 'sendby'), -2) == [3,8] ? 1 : 0;
demo
Update on base of comments
// get array with two last values
$temp = array_slice(array_column($array, 'sendby'), -2);
foreach($array as &$x) {
// If current send by is in $temp array
if(in_array($x['sendby'], $temp)) {
$x['last'] = 1;
}
else {
$x['last'] = 0;
}
}
print_r($array);
You can use an array to assist the existing ocurrences of that id. I have an working example (Tested on php sandbox):
$array = array(
0 => array
(
'sendby' => 3,
'refresh' => 0,
),
1 => array
(
'sendby' => 3,
'refresh' => 1,
),
2 => array
(
'sendby' => 8,
'refresh' => 1,
)
);
$ocurrences = [];
foreach($array as $key => $elem ){
$id = $elem['sendby'];
if (isset($ocurrences[$id])) {
$array[$ocurrences[$id]]['last'] = 0;
$array[$key]['last'] = 1;
$ocurrences[$id] = $key;
} else {
$ocurrences[$id] = $key;
$array[$key]['last'] = 1;
}
}
echo print_r($array, 1);
The result:
Array
(
[0] => Array
(
[sendby] => 3
[refresh] => 0
[last] => 0
)
[1] => Array
(
[sendby] => 3
[refresh] => 1
[last] => 1
)
[2] => Array
(
[sendby] => 8
[refresh] => 1
[last] => 1
)
)
Basically I used an array with the ocurrences of the 'sendby' index of the array. The $occurences array has the elements with the key of the last checked element.
Lets suppose your array is $array;
You could iterate through it and if it's the last element, then set [last] to 1, else set to 0;
Try to run the below code after your array is populated.
$i =1;
foreach($array as $ar) {
$ar->last = ($i == count($array) && ($ar->sendby == 3 || $ar->sendby == 8)) ? 1 : 0;
$i++;
}
$count = count($arr) ;
$i = 0;
foreach($arr as $key=>$val) {
if(++$I === $count) {
echo "last element" ;
}
}

Show the count of inner array values in the following example

I have the following array i want to show the count of inner array values Please help me out.
Array
(
[e1549b20-4cad-11e6-85b4-73d5cb14d4fe] => Array
(
[a029e160-4337-11e6-8db4-ad7de57838b4] => Array
(
[0] => b46b70a2-481a-11e6-8b19-00262d644487
[1] => b4696a1e-481a-11e6-8b19-00262d644487
)
[40eca780-48ef-11e6-8a04-eb9fe0a25fc5] => Array
(
[0] => b46b70a2-481a-11e6-8b19-00262d644487
[1] => b4696a1e-481a-11e6-8b19-00262d644487
)
[e5926390-44cf-11e6-bc85-19a184fbd10f] => Array
(
[0] => b4696a1e-481a-11e6-8b19-00262d644487
)
[51a44c00-4a53-11e6-81fe-313fe319f95b] => Array
(
[0] => b4696a1e-481a-11e6-8b19-00262d644487
)
)
)
Please Try with this functionality :
function getCount($arr, $count = 0) {
foreach ($arr as $value) {
if (is_array($value)) {
$count = getCount($value, $count);
} else {
$count = $count + 1;
}
}
return $count;
}
echo getCount($arr);

How to build custom array in multi level foreach?

Here is the raw data
Array
(
[name] => me
[tickets] => Array
(
[1] => Array
(
[equipment] => Array
(
[1] => Array
(
[name] => DVR
[received] => 10
)
[2] => Array
(
[name] => DCT
[received] => 3
)
)
)
[2] => Array
(
[equipment] => Array
(
[1] => Array
(
[name] => DVR
[received] => 4
)
[2] => Array
(
[name] => DCT
[received] => 6
)
)
)
)
)
Users have multiple tickets, but each ticket has the same item with different 'received' amounts. I would like to sum the received amount into one variable/array.
Here is a demo of how I would like to get it to work like
Array
(
[name] => me
[equipment] => Array
(
[DVR] => 14
[DCT] => 9
)
)
Here is my most recent failed attempt at building my own array from a multidimensional array.
foreach($data as $user){
$sum = [];
$sum['name'] = $user->name;
$sum['equipment'] = [];
foreach($user->tickets as $ticket){
foreach($ticket->equipments as $eqpt){
$sum['equipment'][$eqpt['name']] += $eqpt['pivot']['received'];
}
}
print_r($sum);
}
Please try the following code. There's only a single user in your $data, though, so you need to do $data = [$data]; first.
foreach ($data as $user) {
$sum = [];
$sum['name'] = $user['name'];
$sum['equipment'] = [];
foreach($user['tickets'] as $ticket){
foreach($ticket['equipment'] as $eqpt){
$sum['equipment'][$eqpt['name']] += $eqpt['received'];
}
}
print_r($sum);
}
PHP arrays are accessed with square bracket syntax
There's probably a typo in $ticket->equipments.
Try with this:
$array = $data; //$data is your array
$sum = array('name' => $array['name'], 'equipment' => array());
foreach($array['tickets'] as $row) {
for($i = 0; $i < count($row); $i++) {
foreach($row['equipment'] as $infos) {
$sum['equipment'][$infos['name']] += $infos['received'];
//print_r($infos);
}
}
}
print_r($sum);
well, after much googling and trial and error this appears to work
$sum = [];
// $data is a collection returned by Laravel
// I am converting it to an array
foreach($data->toArray() as $user){
$items = [];
foreach($user['tickets'] as $ticket){
foreach($ticket['equipments'] as $eqpt){
$name = $eqpt['name'];
if (! isset($items[$name]))
{
$items[$name] = $eqpt['received'];
} else {
$items[$name] += $eqpt['received'];
}
}
}
$sum[] = [
'name' => $user['name'],
'equipment' => $items
];
}
#tsnorri #Adrian Cid Almaguer

php sum of array

I have the following array with multiple levels. I wish to get the sum total of [price], [adults] and [childern] but have not been able traverse the levels.
The answer I should get with this example is price=380 adults=5 and children=1
Array (
[8] => Array (
[2] => Array (
[num_rooms] => 2
[adults] => Array (
[0] => 1
[1] => 1
)
[children] => Array (
[0] => 0
[1] => 0
)
[prices] => Array (
[0] => 50
[1] => 50
)
[price] => 130
[supp] => 30
)
[3] => Array (
[num_rooms] => 1
[adults] => Array (
[0] => 1
)
[prices] => Array (
[0] => 100
)
[price] => 150
[supp] => 50
)
)
[1] => Array (
[2] => Array (
[num_rooms] => 2
[adults] => Array (
[0] => 1
[1] => 1
)
[children] => Array (
[0] => 1
[1] => 0
)
[prices] => Array (
[0] => 75
[1] => 75
)
[price] => 170
[supp] => 20
)
)
)
Thanks
Two loops and a helper array:
$sums = array ( 'price' => 0, 'adults' => 0, 'children' => 0 );
foreach($array as $outer) {
foreach($outer as $inner) {
$sums['price'] += $inner['price'];
$sums['adults'] += array_sum($inner['adults']);
$sums['children'] += array_sum($inner['children']);
}
}
print_r($sums);
With a more dynamic version of the inner loop:
foreach($array as $outer) {
foreach($outer as $inner) {
foreach($sums as $key => &$v)
$v += is_array($inner[$key])
? array_sum($inner[$key])
: $inner[$key];
}
}
This should work:
$price = 0;
$adults = 0;
$children = 0;
foreach($arr as $l1_key => $l1_value) // iterates over the first level array
{
foreach($l1_value as $l2_key => $l2_value) // iterates over second level arrays
{
$price += $l2_value['price']; // add up price totals
foreach($l2_value['adults'] as $value) // iterate through adults array values
{
$adults += $value; // sum up adult count
}
foreach($l2_value['children'] as $value) // iterate through children array values
{
$children += $value; // sum up children count
}
}
}
// now $price, $adults, and $children contain the totals for each
I didn't test this code but at the same time I don't know how you got 380.. I'm seeing 350?
$sums = getSum($arr);
print_r($sums);
function getSum($arr) {
$sums = array();
$sums2 = array();
$sums['adults'] = 0;
$sums2['adults'] = 0;
$sums['children'] = 0;
$sums2['children'] = 0;
$sums['prices'] = 0;
$sums2['prices'] = 0;
foreach ($arr as $key => $value) {
$do_not_recurse = false;
switch ($key) {
case 'adults':
$do_not_recurse = true;
foreach ($value as $adults)
$sums['adults'] += $adults;
break;
case 'children':
$do_not_recurse = true;
foreach ($value as $children)
$sums['children'] += $children;
break;
case 'prices':
$do_not_recurse = true;
foreach ($value as $price)
$sums['prices'] += $price;
break;
default:
break;
}
if (is_array($value))
$sums2 = getSum($value);
}
$sums['adults'] += $sums2['adults'];
$sums['children'] += $sums2['children'];
$sums['prices'] += $sums2['prices'];
return $sums;
}
Handles any depth or array structure and just picks out the terms with the names you are looking for:
function find($term, $array) {
$count = 0;
foreach ($array as $item)
if (is_array($item)) $count += find($term, $item);
if (isset($array[$term]) {
if (is_array($array[$term])) $count += array_sum($array[$term]);
else $count += $array[$term];
}
return $count;
}
echo count('price', <the array>);
echo count('adults', <the array>);
echo count('children', <the array>);

Categories