Counting arrays inside of an array? PHP - php

How to specifically count arrays inside of an array?
For example:
$array = [ 10, 'hello', [1, 2, 3, ['hi', 7]], [15, 67], 12 ]
Output should be 3.

You can use a recursive function for that. Let me give you an example:
<?php
$array = [ 10, 'hello', [1, 2, 3, ['hi', 7]], [15, 67], 12 ];
$arrayCount = 0; # this variable will hold count of all arrays found
# Call a recursive function that starts with taking $array as an input
# Recursive function will call itself from within the function
countItemsInArray($array);
function countItemsInArray($subArray) {
# access $arrayCount that is declared outside this function
global $arrayCount;
# loop through the array. Skip if the item is NOT an array
# if it is an array, increase counter by 1
# then, call this same function by passing the found array
# that process will continue no matter how many arrays are nested within arrays
foreach ($subArray as $x) {
if ( ! is_array($x) ) continue;
$arrayCount++;
countItemsInArray($x);
}
}
echo "Found $arrayCount arrays\n";
Example
https://rextester.com/SOV87180
Explanation
Here's how the function would operate.
[ 10, 'hello', [1, 2, 3, ['hi', 7]], [15, 67], 12 ] is sent to countItemsInArray function
This function looks at each item in the array
10 is reviewed. It's not an array, so the function goes to the next item
'hello' is reviewed. It's not an array, so the function goes to the next item
[1, 2, 3, ['hi', 7]] is evaluated. It is an array, so arrayCount is increased to 1 and the same function is called but the input to the function now is [1, 2, 3, ['hi', 7].
Remember, this same function called with the entire array is not dead. It's just waiting for this countItemsInArray([1, 2, 3, ['hi', 7]]) to be done
1 is evaluated. It's not an array, so the next item is evaluated
2 is evaluated ...
3 is evaluated ...
['hi', 7] is evaluated. It is an array. So, array count is increased to 2
countItemsInArray(['hi', 7]) is called.
Remember that countItemsInArray with the full array as the parameter AND countItemsInArray([1, 2, 3, ['hi', 7]]) are now waiting for countItemsInArray(['hi', 7]) to be done
hi is evaluated. That's not an array, so the function tests the next item
7 is evaluated. That's not an array either. So, the that function completes, giving control back to countItemsInArray([1, 2, 3, ['hi', 7]])
countItemsInArray([1, 2, 3, ['hi', 7]]) recognizes that it has nothing more to evaluate. Control is given back to countItemsInArray($array).
[15, 67] is evaluated. It is an array, so array count is increased to 3
countItemsInArray([15, 67]) is called, which evaluates 15 and 16 and determines that none of them are an array, so it gives control back to countItemsInArray($array)
countItemsInArray($array) evaluates 12 and determines that's not an array either. So, it ends its work.
Then, echo echoes out that array count is 3.

Recursively iterate your input array and restart the tally variable upon entering a new level in the array. Every time an array is encountered, add one and recurse. Pass up the tallies from the deeper levels and when the levels are completely traversed, return the top level's cumulative tally.
Code: (Demo)
$array = [10, [[[]],[]], 'hello', [1, 2, 3, ['hi', 7]], [15, 67], 12];
function array_tally_recursive(array $array): int {
$tally = 0;
foreach ($array as $item) {
if (is_array($item)) {
$tally += 1 + array_tally_recursive($item);
}
}
return $tally;
}
echo array_tally_recursive($array);

Related

How do I get the end element of an array

I have an array (as shown below). It has a and b, the numbers inside of each of them. However, when I use the end() function, it gives me b's array. I want the actual b letter. to be printed, not the number array. How can I do this?
<?php
$array = array("a" => array(1, 2, 3),
"b" => array(4, 5, 6));
$end = end($array);
print_r($end); // gives me 4, 5, 6. I want the value b
Use end with array_keys instead:
$array = array("a" => array(1, 2, 3),
"b" => array(4, 5, 6));
$keys = array_keys($array);
$end = end($keys);
print_r($end);
Note that since end adjusts the array pointer (hence you can't pass the output from array_keys directly to end without a notice level error), it's probably preferable to simply use
echo $keys[count($keys)-1];
Simply
$array = array("a" => array(1, 2, 3),"b" => array(4, 5, 6));
end($array);
echo key($array);
Output
b
Sandbox
the call to end puts the internal array pointer at the end of the array, then key gets the key of the current position (which is now the last item in the array).
To reset the array pointer just use:
reset($array); //moves pointer to the start
You cant do it in one line, because end returns the array element at the end and key needs the array as it's argument. It's a bit "Weird" because end moves the internal array pointer, which you don't really see.
Update
One way I just thought of that is one line, is to use array reverse and key:
echo key(array_reverse($array));
Basically when you do array_reverse it flips the order around and returns the reversed array. We can then use this array as the argument for key(), which gets the (current) first key of our now backwards array, or the last key of the original array(sort of a double negative).
Output
b
Sandbox
Enjoy!
A simple way to do it would be to loop through the keys of the array and store the key at each index.
<?php
$array = array("a" => array(1, 2, 3),
"b" => array(4, 5, 6));
foreach ($array as $key => $value) $end = $key;
// This will overwrite the value until you get to the last index then print it out
print_r($end);

Get array containing smallest values using min()

The documentation for min() shows the following example:
// Multiple arrays of the same length are compared from left to right
// so in our example: 2 == 2, but 4 < 5
$val = min(array(2, 4, 8), array(2, 5, 1)); // array(2, 4, 8)
Given the following code:
$input = [
[3, 6],
[2, 9],
];
var_dump(min(...$input)); // returns [2, 9] as expected
If you make the same array associative, it fails and always seems to just return the first array:
$input = [
["three" => 3, "six" => 6],
["two" => 2, "nine" => 9],
];
var_dump(min(...$input)); // returns ["three" => 3, "six" => 6]
Why?
Here's an example
According to the documentation values are compared using the standard comparison rules.
In the table of "comparison with various types" there, it states that if both operands are arrays and a key in operand 1 is not present in operand 2, then the arrays are not comparable. This is why min simply returns whatever is the first value in your array.
Specifically, arrays are compared as follows:
If one array has fewer values than the other, it is smaller.
Otherwise if any key in operand 1 is not in operand 2, the arrays are uncomparable.
For each value in operand 1 in turn, compare with the value with the same key in operand 2.
If the same, continue comparing values.
Otherwise the smaller array is the one with the smaller value.
Because they are not comparable, min is simply returning the first array in the list. If you swap the order, the other array will be returned. You can see this if you sort the array with sort($input). Every time you sort it the array is reversed.
To get the behaviour you desire, sort the arrays based on their values and then fetch the first element. But be aware that this will depend which key you defined first, so ["three" => 3, "six" => 6] is not the same as ["six" => 6, "three" => 3].
usort($input, function($a, $b) { return array_values($a) <=> array_values($b); });
var_dump($input[0]);
Just convert them to simple arrays and then return the associative array associated to the result of min.
<?php
function array_min_assoc(){
$args = func_get_args();
$not_assoc = array_map('array_values',$args);
$min = min(...$not_assoc);
$key = array_search($min, $not_assoc);
if ($key !== false){
return $args[$key];
}
}
$input = [
["three" => 3, "six" => 6],
["two" => 2, "nine" => 9],
];
var_dump(array_min_assoc(...$input));
/* returns
array(2) {
["two"] => int(2)
["nine"]=> int(9)
}
*/

iteratively looping through every nth element of an array and deleting it?

Hi i want to delete every nth element of an array iteratively.
For example if I have an array like this
$input = array (1, 2, 3, 4, 5, 6, 7, 8);
and say I need to remove every 4th element.
In the first iteration 5 will be removed, then 1, then 6, then 3 then 2, then 4, then 8
The number 7 will be left in the array, I want to return that !
Thanks for your help

How to merge arrays in PHP without key preservation?

Am I overlooking a function in PHP that will merge arrays without preserving keys? I've tried both ways of these ways: $arrayA + $arrayB and array_merge($arrayA, $arrayB) but neither are working as I expected.
What I expect is that when I add array(11, 12, 13) and array(1, 2, 3) together that I would end up with array(11, 12, 13, 1, 2, 3).
I created a function of my own which handles it properly, though I was trying to figure out if it was the best way of doing things or if there's an easier or even a build in way that I'm just not seeing:
function array_join($arrayA, $arrayB) {
foreach($arrayB as $B) $arrayA[] = $B;
return $arrayA;
}
Edit:
array_merge() was working as intended, however I had the function running in a loop and I was using the incorrect variable name inside the function, so it was only returning a partial list as is what I was experiencing. For example the loop I was using ended on array(13, 1, 2, 3).
Have you actually tested your code? because array_merge should be enough:
From the documentation of array_merge:
Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. (emphasis are mine)
<?php
$a1 = array(11, 12, 13);
$a2 = array(1, 2, 3);
$x = array_merge($a1, $a2);
print_r($x);
It print this on my console:
Array
(
[0] => 11
[1] => 12
[2] => 13
[3] => 1
[4] => 2
[5] => 3
)
$arr1 = array(11, 12, 13);
$arr2 = array(1, 2, 3);
print_r(array_merge($arr1,$arr2));
Try this :
function array_join($arrayA, $arrayB) {
foreach($arrayB as $B) $arrayA[count($arrayA)] = $B;
return $arrayA;
}

Is there a PHP function to count the number of times a value occurs within an array?

I need to count the number of times a value occurs in a given array.
For example:
$array = array(5, 5, 2, 1);
// 5 = 2 times
// 2 = 1 time
// 1 = 1 time
Does such a function exist? If so, please point me to it in the php docs... because I can't seem to find it.
Thanks.
Yes, it's called array_count_values().
$array = array(5, 5, 2, 1);
$counts = array_count_values($array); // Array(5 => 2, 2 => 1, 1 => 1)
array_count_values

Categories