For example i have an array like this [-1,-1,-1,-1,-1,-1,2.5,-1,-1,8.3]
I want to count the element which are not -1 like except of the -1. Is there any function in php to get this ? One approach which i think is
Count the total array - count of the -1 in the array.
how can we achieve this.
P.S : please provide me a comment why this question deserve negative vote.
Like #MarkBaker said, PHP doesn't have a convenient function for every single problem, however, you could make one yourself like this:
$arr = [-1,-1,-1,-1,-1,-1,2.5,-1,-1,8.3];
function countExcludingValuesOfNegativeOne ($arr) {
return count($arr) - array_count_values(array_map('strval', $arr))['-1'];
}
echo countExcludingValuesOfNegativeOne($arr); // Outputs `2`.
It just counts the whole array, then subtracts the number of negative 1s in the array. Because PHP throws an error if any element in the array isn't a string 1 when using array_count_values, I've just converted all elements of the array to a string using array_map('strval', $arr) 2
you can use a for loop counter skipping for a specific number.
function skip_counter($array,$skip){
$counter = 0;
foreach ($array as $value) {
if ($value != $skip) $counter++;
}
return $counter;
}
then you call skip_counter($your_list, $number_to_be_skipped);
Related
I am attempting to write a function that will cycle through an array and perform a task based on its value.
For example:
foreach ($content as $i => $c) {
cycle(array('<div class="row">', '', ''), $i)
$content;
cycle(array('', '', '</div>'), $i)
}
The function:
function cycle($cycles, $i) {
if ($cycles[$i] !== '') {
echo $cycles[$i];
}
}
This works fine if the length (count) of the array I am passing into cycle() matches the number of forloop iterations where I am calling the function. However, if the number of iterations is greater obviously I get errors.
Some of you may have guessed that I am trying to wrap content with a <div class="row"></div> at the specified number of iterations or cycles. I do not want to use modulo.
I want the cycle() function to ignore empty values and only output it's value if it is not an empty string or null.
Ideally, if my array is too short, I want to keep repeating its own indices starting at 0 until it's indices count matches $i.
So if i had an array such as $arr = array(a,b,c,d); amd and pass it to my cycle($arr) function and this runs in a forloop 7 times, I want to somehow fill in the array thusly: array(a,b,c,d,a,b,c) . so I can output the required number of opening and closing divs.
Any Suggestions?
Try this (working example)
function cycle($cycles, $i) {
$j=$i%count($cycles);
if ($cycles[$j] !== '') {
echo $cycles[$j];
}
}
I use PHP/7.2.0beta3. So I want to create a custom function to reverse an array in PHP. If the array is (1,2,3) the functions turns it to (3,2,1).
I thought I should use the array_pop, grab the last value of the array and pass it to another array.
The problem
Here is the code I wrote. Just copy it and run it as PHP. I dont know why it stops in the middle of the array and does not continue till the end.
$originalarray = range(0, 100, 5);//works
echo '<br> original array <br>';
print_r($originalarray); // 0-100, with 5 step
function customreverse($x){
echo '<br> original array in function <br>';
print_r($x); //works, 0-100, with 5 step
echo '<br> sizeof in function '.sizeof($x).'<br>'; //works, is 21
for($a=0; $a<sizeof($x); $a++){
$reversearray[$a] = array_pop($x);
echo '<br> reversearray in for loop <br>';
print_r($reversearray);//stops at 50
echo '<br> a in for loop <br>';
echo $a;//stops at 10
}
echo '<br> reverse in function <br>';
print_r($reversearray);////stops at 50
}
customreverse($originalarray);
The same problem occurs even if I replace sizeof with count. Or $a<sizeof($x) with $a<=sizeof($x). Why does it stop and does not traverse the whole array? What am I missing here?
Thanks
sizeof (or count) is evaluated on every iteration of the loop and the array shrinks on each iteration. You need to store the original count in a variable. For Example (I removed a few lines to focus on the issue):
<?php
$originalarray = range(0, 100, 5);//works
function customreverse($x){
$origSize=sizeof($x);
for($a=0; $a<$origSize; $a++){
$reversearray[$a] = array_pop($x);
}
return($reversearray);//stops at 50 (Now it doesn't)
}
print_r(customreverse($originalarray));
jh1711 properly explained that your loop ends early because the middle statement in for(statement1; statement2; statement3) gets executed each iteration, and because you're popping the original array within the loop, sizeOf() returns a smaller number each time.
You could compact your code a bit, by building your reverse array like so:
while(!empty($original)) $reverse[] = array_pop($original);
If you want to preserve key=>value bindings (meaning reverse keys as well, so that the same keys will bind to the same values), you could do:
while(!empty($original)):
$val = end($original); // set pointer at end of array
$reverse[key($original)] = $val;
endwhile;
If you want to modify the array in-place (not create a 2nd array), you could do:
for($i=0, $j=sizeof($original); $i < $j; $i++){
array_splice($original,$i,0,array_pop($original));
} // pop last element and insert it earlier in the array
$players = array(
array('Lionel Messi', 'Luis Suarez', 'Neymar Jr'),
array('Ivan Rakitic', 'Andres Iniesta', 'Sergio Busquets'),
array('Gerrard Pique', 'Mascherano', 'Denis Suarez', 'Jordi Alba'),
array('MATS'),
array('Arda Turan', 'Munir El Hadadi', 'Umtiti')
);
Now i am trying to echo the number of all the elements within the boundary of this array $players. For example, there are 3 elements in the first, 3 in the second. There are 4 elements in the third, 1 element in the 4th and 3 elements in the last one. Altogether these elements are 14 elements. Now i want to display 'Total Players: 14'. I can show the number of categories (5) using count() function but can't count the total elements(14). I tried different approaches but couldn't succeed.
count() should be able to do this for you directly, using the COUNT_RECURSIVE flag:
$playerCount = count($players, COUNT_RECURSIVE) - count($players);
// $playerCount is now equal to 14
The subtraction of the normal count is because counting recursively adds the keys of the outer array in to the sum of elements, which just needs to be subtracted from the recursive count.
The native count() method can do that.
$count = count($players, COUNT_RECURSIVE) - count($players);
Because the recursive count will also count the number of $player groups you have, you have to subtract that number from the recursive count.
From the php documentation for count:
If the optional mode parameter is set to COUNT_RECURSIVE (or 1), count() will recursively count the array. This is particularly useful for counting all the elements of a multidimensional array.
One other way, pretty self-explanatory:
$count = array_sum(array_map('count', $players));
$count=0;
foreach($players as $row) $count+=count($row);
$count is now 14.
Live demo
You can use:
count($array, COUNT_RECURSIVE);
check count manual
Declare a variable initialised to 0 to accumulate the number of elements. Then, iterate the first array (which contains the other arrays), and for each element (which is also an array) use count() to obtain the number of elements and add that value to the accumulator variable.
$num_players = 0;
foreach($players as $row) {
$num_players += count($row);
}
I have a foreach loop like below code :
foreach($coupons as $k=>$c ){
//...
}
now, I would like to fetch two values in every loop .
for example :
first loop: 0,1
second loop: 2,3
third loop: 4,5
how can I do ?
Split array into chunks of size 2:
$chunks = array_chunk($coupons, 2);
foreach ($chunks as $chunk) {
if (2 == sizeof($chunk)) {
echo $chunk[0] . ',' . $chunk[1];
} else {
// if last chunk contains one element
echo $chunk[0];
}
}
If you want to preserve keys - use third parameter as true:
$chunks = array_chunk($coupons, 2, true);
print_r($chunks);
Why you don't use for loop like this :
$length = count($collection);
for($i = 0; $i < $length ; i+=2)
{
// Do something
}
First, I'm making the assumption you are not using PHP 7.
It is possible to do this however, it is highly, highly discouraged and will likely result in unexpected behavior within the loop. Writing a standard for-loop as suggested by #Rizier123 would be better.
Assuming you really want to do this, here's how:
Within any loop, PHP keeps an internal pointer to the iterable. You can change this pointer.
foreach($coupons as $k=>$c ){
// $k represents the current element
next($coupons); // move the internal array pointer by 1 space
$nextK = current($coupons);
prev($coupons);
}
For more details, look at the docs for the internal array pointer.
Again, as per the docs for foreach (emphasis mine):
Note: In PHP 5, when foreach first starts executing, the internal array pointer is automatically reset to the first element of the
array. This means that you do not need to call reset() before a
foreach loop. As foreach relies on the internal array pointer in PHP
5, changing it within the loop may lead to unexpected behavior. In PHP
7, foreach does not use the internal array pointer.
Let's assume your array is something like $a below:
$a = [
"a"=>1,
"b"=>2,
"c"=>3,
"d"=>4,
"e"=>5,
"f"=>6,
"g"=>7,
"h"=>8,
"i"=>9
];
$b = array_chunk($a,2,true);
foreach ($b as $key=>$value) {
echo implode(',',$value) . '<br>';
}
First we split array into chunks (the parameter true preserves the keys) and then we do a foreach loop. Thanks to the use of implode(), you do not need a conditional statement.
well this'd be 1 way of doing it:
$keys=array_keys($coupons);
for($i=0;$i<count($keys);++$i){
$current=$coupons[$keys[$i]];
$next=(isset($keys[$i+1])?$coupons[$keys[$i+1]]:NULL);
}
now the current value is in $current and the next value is in $next and the current key is in $keys[$i] and the next key is in $keys[$i+1] , and so on.
I a string that is coming from my database table say $needle.
If te needle is not in my array, then I want to add it to my array.
If it IS in my array then so long as it is in only twice, then I still
want to add it to my array (so three times will be the maximum)
In order to check to see is if $needle is in my $haystack array, do I
need to loop through the array with strpos() or is there a quicker method ?
There are many needles in the table so I start by looping through
the select result.
This is the schematic of what I am trying to do...
$haystack = array();
while( $row = mysql_fetch_assoc($result)) {
$needle = $row['data'];
$num = no. of times $needle is in $haystack // $haystack is an array
if ($num < 3 ) {
$$haystack[] = $needle; // hopfully this adds the needle
}
} // end while. Get next needle.
Does anyone know how do I do this bit:
$num = no. of times $needle is in $haystack
thanks
You can use array_count_values() to first generate a map containing the frequency for each value, and then only increment the value if the value count in the map was < 3, for instance:
$original_values_count = array_count_values($values);
foreach ($values as $value)
if ($original_values_count[$value] < 3)
$values[] = $value;
As looping cannot be completely avoided, I'd say it's a good idea to opt for using a native PHP function in terms of speed, compared to looping all values manually.
Did you mean array_count_values() to return the occurrences of all the unique values?
<?php
$a=array("Cat","Dog","Horse","Dog");
print_r(array_count_values($a));
?>
The output of the code above will be:
Array (
[Cat] => 1,
[Dog] => 2,
[Horse] => 1
)
There is also array_map() function, which applies given function to every element of array.
Maybe something like the following? Just changing Miek's code a little.
$haystack_count = array_count_values($haystack);
if ($haystack_count[$needle] < 3)
$haystack[] = $needle;