How can I exclude null values from a count on an array?
since count always includes null values in the counting!
count(array_filter($array, function($x) {return !is_null($x); })
function count_nonnull($a) {
$total = 0;
foreach ($a as $elt) {
if (!is_null($elt)) {
$total++;
}
}
return $total;
}
Try using a foreach loop.
foreach($array as $index=>$value) {
if($value === null) unset($array[$index]);
}
echo count($array);
Or if you don't want to modify the array:
function myCount($arr) {
$count = 0;
foreach($arr as $index=>$value) {
if($value !== null) $count++;
}
return $count;
}
echo myCount($array);
// easiest way
echo count(array_filter($array));
instructions
Related
I have an array:
$arr1 = [1,2,2,3,3,3];
Is there any method by which I can delete a duplicate value once like,
some_function($arr1,3);
which gives me the ouput $arr1 = [1,2,2,3,3]
As per the comment, check if there are more than one of the element you're searching for, then find and remove one of them.
function remove_one_duplicate( $arr, $target ) {
if( count( array_keys( $arr, $target ) ) > 1 ) {
unset( $arr[array_search( $target, $arr )] );
}
return $arr;
}
This should work...
function removeduplicate($myarray,$needle) {
if (($nmatches = count($matches = array_keys($myarray,$needle))) >= 2) {
for ($i=0; $i<$nmatches; $i++) {
if ($matches[$i+1] == (1+$matches[$i])) {
array_splice($myarray,$matches[$i],1);
break;
}
}
}
return $myarray;
}
To use the function...
$arr1 = [1,2,2,3,3,3,4,7,3,3];
$newarray = removeduplicate($arr1,3)
print_r($newarray);
EDITED:
If you want the function to modify your original array directly, you can do it (the function will return true if a character has been removed or false if not)...
function removeduplicate(&$myarray,$needle) {
if (($nmatches = count($matches = array_keys($myarray,$needle))) >= 2) {
for ($i=0; $i<$nmatches; $i++) {
if ($matches[$i+1] == (1+$matches[$i])) {
array_splice($myarray,$matches[$i],1);
return true;
}
}
}
return false;
}
So, now you can do...
$arr1 = [1,2,2,2,2,2,3,3,3,4,2,2];
removeduplicate($arr1,2);
print_r($arr1);
This function will copy the array skipping only the second instance of the specified element.
function removeOnce($array, $elem) {
$found = 0;
$result = [];
foreach ($array as $x) {
if ($x == $elem && (++$found) == 2) {
continue;
}
$result[] = $x;
}
return $result;
}
I got an Array:
$myArrays = array(5,4,3,2,1);
foreach($myArrays as $myArray)
{
echo $myArray;
$val = 3;
if($myArray == $val)
{
break;
}
}
Output: 5,4,3
I would want it to be like
output: 3,2,1
is this possible?
You can use the following snippet.
The first element of array is always the left one, when you define it.
<?php
foreach($myArrays as $myArray)
{
if ($myArray <= 3) {
echo $myArray;
}
}
$myArrays = array(5,4,3,2,1);
foreach($myArrays as $myArray)
{
$val = 3;
if($myArray > $val)
{
continue;
}
echo $myArray;
}
Simply have a boolean variable outside loop to keep track of wheter you got the element you're looking for.
Skip the loop (By using continue keyword) until you find that element.
So your will look something like this,
$foundelement=false;
foreach($myArrays as $myArray)
{
$val = 3;
if(!$foundelement && $myArray != $val)
{
continue;
} else {
$foundelement=true;
}
if($foundelement) {
echo $myArray;
}
}
Demo: https://eval.in/620081
I have the following code that returns the indexed position of a value which its key matches the provided value in the parameter of the function($haystack).
$results = array("098"=>90,"099"=>89,"100"=>77,"101"=>77);
function getPosition($results,$StudentID){
arsort($results);
$index = 1;
$exists = '';
$keys = array_keys($results);
foreach($keys as $key)
{
if($key == $StudentID)
{
$score = $results[$key];
$position = $index;
}
$index++;
}
return $position;
}
echo getPosition($results,"098").'<br />';
echo getPosition($results,"099").'<br />';
echo getPosition($results,"100").'<br />';
echo getPosition($results,"101").'<br />';
The results are listed below:
90=1
89=2
77=4
77=3
Now my problem is:
1. I don't know how to get the function to return same position for two similar values(eg. 77);
edit: The StudentID parameter in the function is the key for array values.
eg. 098 is a key in the array and its the value for a particular StudentID
Simple return the positions as array.
$results = array("098"=>90,"099"=>89,"100"=>77,"101"=>77);
function getPosition($results,$StudentID)
{
arsort($results);
$index = 1;
$exists = '';
$keys = array_keys($results);
$position = array();
foreach($keys as $key)
{
if($key == $StudentID)
{
$score = $results[$key];
$position[] = $index;
}
$index++;
}
return $position;
}
print_r(getPosition($results,"77"));
Should you be searching for values rather than keys?
$results = array("098"=>90,"099"=>89,"100"=>77,"101"=>77);
function getPosition($results, $StudentID) {
$index = 1;
$indexes = array();
foreach ($results as $key=>$value) {
if ($value == $StudentID) $results[] = $index;
$index++;
}
return $indexes;
}
print_r(getPosition($results, "77"));
I have a multidimensional array $array["A"]["B"]["C"]["D"]. The list is longer.
Is there a wildcard that I can use to get ["D"] value in let say ["B"] array?
Something like this, $array["A"]["B"][*]["D"] ?
or $array[*]["B"][*]["D"] ?
Example, I would like to get all prices that were bought on February regardless of the year.
$array[2013][2][23]["ItemName"]["ItemPrice"] .....
If this would work, it would be really wonderful
$array[*][2][*][*]["ItemPrice"]..
any idea?
You could do multiple foreach to loop though every nested array that you want to loop though.
foreach ($array as $a) {
foreach ($a["B"] as $c) {
foreach ($c as $d) {
// Do something with $d
}
}
}
This would be $array[*]["B"][*][*]
Edit: You could combine my suggestion with a while loop.
$innerArray = $array;
while (true) {
foreach ($array as $key => $value) {
if ($key == "D") {
// Do something with this value
} else if (is_array($value)) {
$innerArray = $value;
} else {
break;
}
}
}
Thanks to #Sepehr-Farshid it just crossed my mind that I can use recursive function (Something that I haven't use for quiet a while. So here a example.
$newarray = array();
$tempArray = $oldarray;
$levels[] = 1;
$keys[] = 2;
$levels[] = 4;
$keys[] = "ItemPrice";
$lastLevel =4;
recurArray($tempArray, 0);
function recurArray($array, $level)
{
foreach($array as $key => $value) {
if(array_search($level, $GLOBALS["levels"]) {
$tempKey = array_search($level, $GLOBALS["levels"];
if($key == $GLOBALS["keys"][$tempKey] {
if($level == $GLOBALS["lastLevel"]) $GLOBALS["newarray"] = $value;
else recurArray($value, $level + 1);
}
else { return; }
}
else { recurArray($value, $level + 1); }
}
}
this might not be the optimum way, but it will work and can be refined. :D
I want to remove some duplicate values on an array, but there is a condition that the script has to ignore the array that contains a specific word.
Below code is adapted from PHP: in_array.
$array = array( 'STK0000100001',
'STK0000100002',
'STK0000100001', //--> This should be remove
'STK0000100001-XXXX', //--> This should be ignored
'STK0000100001-XXXX' ); //--> This should be ignored
$ignore_values = array('-XXXX');
if(make_unique($array, $ignore_values) > 0) {
//ERROR HERE
}
The function to make the array unique is:
function make_unique($array, $ignore) {
$i = 0;
while($values = each($array)) {
if(!in_array($values[1], $ignore)) {
$dupes = array_keys($array, $values[1]);
unset($dupes[0]);
foreach($dupes as $rmv) {
$i++;
}
}
}
return $i;
}
I have tried to use if(!in_array(str_split($values[1]), $ignore)) ... but it just the same.
The array should become like:
STK0000100001
STK0000100002
STK0000100001-XXXX
STK0000100001-XXXX
How to do that?
Try this one, just remove the print_r(); inside the function when using in production
if(make_unique($array, $ignore_values) > 0) {
//ERROR HERE
}
function make_unique($array, $ignore) {
$array_hold = $array;
$ignore_val = array();
$i = 0;
foreach($array as $arr) {
foreach($ignore as $ign) {
if(strpos($arr, $ign)) {
array_push( $ignore_val, $arr);
unset($array_hold[$i]);
break;
}
}
$i++;
}
$unique_one = (array_unique($array_hold));
$unique_one = array_merge($unique_one,$ignore_val);
print_r($unique_one);
return count($array) - count($unique_one);
}
This should work for >= PHP 5.3.
$res = array_reduce($array, function ($res, $val) use ($ignore_values) {
$can_ignore = false;
foreach ($ignore_values as $ignore_val) {
if (substr($val, 0 - strlen($ignore_val)) == $ignore_val) {
$can_ignore = true;
break;
}
}
if ( $can_ignore || ! in_array($val, $res)) {
$res[] = $val;
}
return $res;
}, array()
);
Otherwise
$num_of_duplicates = 0;
$res = array();
foreach ($array as $val) {
$can_ignore = false;
foreach ($ignore_values as $ignore_val) {
if (substr($val, 0 - strlen($ignore_val)) == $ignore_val) {
$num_of_duplicates++;
$can_ignore = true;
break;
}
}
if ( $can_ignore || ! in_array($val, $res)) {
$res[] = $val;
}
}
Edit: Added duplicate count to the second snippet.