Related
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);
This question already has answers here:
Split array into a specific number of chunks
(7 answers)
Closed 1 year ago.
lets say there is an array like this [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]. How can add every 7 values into a new array that looks like this [[0,1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16]
If the arrays will be equally sized (your example has 7 values in the first array and six in the second - not sure if it's a typo or not) then you can do this:
$array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
$chunkedArrays = array_chunk($array, 7);
print_r($chunkedArrays);
array_chunk documentation here
I have around five arrays, where one of them is containing dates. I would like to sort these after the array containing dates. I know how to sort the date array using "usort". I also know how to sort multiple arrays using "array_multisort", but do not know how to combine these. Is there a way doing this? I hope you can help, and tell me if you need more information to solve my problem :)
Edit:
Here are my arrays:
$fid=array(1, 2, 3, 4, 5, 6, 7, 8);
$ftitle=array("Title1", "Title2", "Title3", "Title4", "Title1", "Title2", "Title3", "Title4");
$fbeskrivelse=array("Beskrivelse1", "Beskrivelse2", "Beskrivelse3", "Beskrivelse4", "Beskrivelse1", "Beskrivelse2", "Beskrivelse3", "Beskrivelse4");
$fstøtter=array(2, 15, 7, 10, 3, 4, 5, 6);
$fstartdato=array('11-01-2012', '01-01-2014', '01-01-2015', '09-02-2013', '01-01-2013', '11-01-2017', '01-01-2018', '01-01-2019');
So this is the kind of result I want (after the sorting):
$fid=array(1, 3, 4, 2, 5, 6, 7, 8);
$ftitle=array("Title1", "Title3", "Title4", "Title2", "Title1", "Title2", "Title3", "Title4");
$fbeskrivelse=array("Beskrivelse1", "Beskrivelse3", "Beskrivelse4", "Beskrivelse2", "Beskrivelse1", "Beskrivelse2", "Beskrivelse3", "Beskrivelse4");
$fstøtter=array(2, 7, 10, 15, 3, 4, 5, 6);
$fstartdato=array('11-01-2012', '01-01-2013', '09-02-2013', '01-01-2014', '01-01-2015', '11-01-2017', '01-01-2018', '01-01-2019');
If I'm understanding correctly, you have (lets say 3) arrays that you want to sort, one of which contains dates, and you want to sort by the dates, and since multisort does not support a callback or sort on dates, you aren't sure what to do?
e.g.
$arr1 = array('2019-05-15', '2019-05-17', '2019-05-13')
$arr2 = array('Wed','Fri','Mon');
$arr3 = array('Pork','Steak','Chicken');
If it were me, I'd probably just parse the dates into unix_time in a new array and use that new array as my sorting "key" to sort the rest, since multisort can do numbers.
(Not tested, just my theory)
$key = array_map('strtotime', $arr1);
array_multisort($key, SORT_ASC, SORT_NUMERIC, $arr1, $arr2, $arr3);
This question already has answers here:
Populate array of integers from a comma-separated string of numbers and hyphenated number ranges
(8 answers)
Closed 6 months ago.
I have a text box that a user can paste a string of comma separated numbers and it puts that into an array. However, in some cases that string may contain numbers separated by a dash and I need to fill in the missing numbers where that dash appears.
Example:
1, 4, 7, 20-25, 31, 46, 100
Needs to become:
1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
How might I go about doing this? The gap wont always be 5 numbers and there could be more than one set of dashed numbers in the string that is input.
Here is one way, without a regex:
It is:
Parsing the input string with str_getcsv() to separate it into its individual elements, then trimming whitespace around each element with trim() and array_map().
Iterating over each element, searching for a dash. If it finds a dash, it found a range of numbers, so it separates them into the start and end indexes by explode()ing on the dash, and forms the correct range between $start and $end with range(). It then merges that newly formed range with what has already been formed as the result using array_merge().
If, during iteration, it didn't find a dash, it assumes you have a literal number, and adds just that number to the resulting array.
That's it!
$input = '1, 4, 7, 20-25, 31, 46, 100';
$entries = array_map( 'trim', str_getcsv( $input));
$result = array();
foreach( $entries as $entry) {
if( strpos( $entry, '-') !== false) {
list( $start, $end) = explode( '-', $entry);
$result = array_merge( $result, range( trim($start), trim($end)));
} else {
$result[] = $entry;
}
}
You can see from this demo that it produces:
Array (
[0] => 1
[1] => 4
[2] => 7
[3] => 20
[4] => 21
[5] => 22
[6] => 23
[7] => 24
[8] => 25
[9] => 31
[10] => 46
[11] => 100 )
Edit: To form the resulting string, instead of the array, you just need a call to implode(), like so:
echo implode( ', ', $result);
This will produce:
1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
$data = '1, 4, 7, 20-25, 31, 46, 100';
$elts = explode(',', $data);
$res = array();
foreach ($elts as $elt) {
$elt = trim($elt);
if (preg_match('/(\d+)-(\d+)/', $elt, $matches) === 1) {
$res = array_merge($res, range($matches[1], $matches[2]));
} else {
$res[] = intval($elt);
}
}
var_dump($res);
My solution :DEMO HERE
First delete spaces using str_replace()
explode() string using , to array of integers.
explode() every element using - to check if it's a range or just a single integer.
if it's a range , loop using for() or range() and add $i to $newArray , else add the element to $newArray.
implode() using , and print the result.
PHP code :
<?php
$str=str_replace(' ', '', '1, 4, 7, 20-25, 31, 46, 100');
$arr = explode(',',$str);
foreach($arr as $elem){
$values=explode('-',$elem);
if(count($values)!=1) for($i=$values[0];$i<=$values[1];$i++) $newArr[]=$i;
else $newArr[]=$elem;
}
echo implode(',',$newArr);
?>
OUTPUT:
1,4,7,20,21,22,23,24,25,31,46,100
Simple code :
split string by delimiter , with explode();
remove space from the beginning and end of a string with trim;
function array_map is used so you don't need to do foreach loop just to apply trim() to every element;
create empty array where you will store new elements;
iterate over each number or range with foreach;
do points 1., 2. and 3. again on every iteration;
split string by delimiter - with explode() even if string doesn't have delimiter - in it; result will be array with one or multi elements;
if point 6. has array with multiple elements, that means that there is range involved, so use function range() to create an array containing a range of elements;
store new numbers to point 4. array with array_merge() function;
when point 4. array is full generated; sort values with sort(), so you don't have output like 5, 3, 1, 4 etc. (delete this function if you don't need this functionality);
remove duplicates with array_unique(), so you don't have output like 4, 4, 4, 4, 5 etc. (delete this function if you don't need this functionality)
to convert array back to string like you inputed, use implode() function.
|
function fillGaps($s) {
$s = array_map('trim', explode(',', $s));
$ss = [];
foreach ($s as $n) {
$n = array_map('trim', explode('-', $n));
if (count($n) > 1) $n = range($n[0], end($n));
$ss = array_merge($ss, $n);
}
sort($ss); # remove if you don't need sorting
$ss = array_unique($ss); # remove if duplicates are allowed
return implode(', ', $ss);
}
Example :
Your example :
echo fillGaps('1, 4, 7, 20 - 25, 31, 46, 100');
# 1, 4, 7, 20, 21, 22, 23, 24, 25, 31, 46, 100
This code will also work for multiple gaps, like :
echo fillGaps('100-105-110');
# 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110
You can even go reverse :
echo fillGaps('10-5');
# 5, 6, 7, 8, 9, 10
# or remove function sort() and output will be 10, 9, 8, 7, 6, 5
Remove duplicates :
echo fillGaps('2-4, 4, 4, 5');
# 2, 3, 4, 5
This can be done without the using a regular expression.
Get the user input, explode with , as the delimiter, and you'll get an array of all numbers.
Now use an if statement to check if the string contains a dash.
If it does, explode it again with the delimiter -. Now you'll get two numbers
Use range() to create an array of numbers within that range
Use implode() to join them by a comma.
As a useful function:
Code:
function fill_string_gaps($input)
{
$parts = explode(',', $input);
$resultArray = array();
foreach ($parts as $part) {
if(strpos(trim($part), '-')) {
list($num1, $num2) = explode('-', $part);
$expanded_num_array = range($num1, $num2);
$resultArray = array_merge($resultArray, $expanded_num_array);
} else {
$resultArray[] = trim($part);
}
}
$comma_separated = implode(', ', $resultArray);
return $comma_separated;
}
Usage:
$input = '1, 4, 7, 20-25, 31, 46, 100';
echo fill_string_gaps($input;)
Test cases:
echo fill_string_gaps('1-5');
echo fill_string_gaps('1-5, 12, 24');
echo fill_string_gaps('2, 2, 4, 5-8');
Output:
1, 2, 3, 4, 5
1, 2, 3, 4, 5, 12, 24
2, 2, 4, 5, 6, 7, 8
See it in action!
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