Hi;

Say I've got 2 simple arrays like

$array1=array(a=>0, b=>, c=>, d=>, e=>); //contains a single value of zero

and

$array2=array(a=>, b=>, c=>, d=>, e=>); //contains only blank/null values

array_sum() will give me a result of "0" for EITHER array, right?

is there a function that will quickly evaluate/differentiate one as having nothing but empty/null keys and the other as having at least ONE actual value...even if it is a zero?

Thanks.

    You could always write a function, e.g.,

    function containsNonNulls($array) {
        foreach ($array as $value) {
            if (!is_null($value)) {
                return true;
            }
        }
        return false;
    }
      
      $array1=array('a'=>0, 'b'=>'', 'c'=>'', 'd'=>'', 'e'=>''); //contains a single value of zero
      $array2=array('a'=>'', 'b'=>'', 'c'=>'', 'd'=>'', 'e'=>''); //contains only blank/null values
      
      if(!empty($array1))
      {
      echo 'not empty, ';
      }
      if(!empty($array2))
      {
      echo 'not empty, ';
      }
      if(!is_null($array1))
      {
      echo 'not null, ';
      }
      if(is_null($array2))
      {
      echo 'not null, ';
      }
      echo array_sum($array1);
      echo array_sum($array2);
      
      

      not empty
      not empty
      not null
      not null

        scrupul0us, the empty string is not the same as null, and what Joseph Sliker wants is a way to determine if the array contains a non-null value. However, an array of nulls is not empty.

          just thinking out loud, would array_search() work?

            dagon wrote:

            just thinking out loud, would array_search() work?

            Considering that my example is just linear search, it just might, assuming that the strict comparison was used.

              I keep coming back to check this while trying to get laserlight's function suggestion working ( have not done too much with building custom functions.)

              Can one put something like "> NULL" or "> ''" into the $needle argument of array_search($needle, $haystack) ?

                Joseph Sliker wrote:

                Can one put something like "> NULL" or "> ''" into the $needle argument of array_search($needle, $haystack) ?

                Oops, I forgot that the linear search is trying to find something that is not present, so array_search() probably will not work since you cannot provide it with a predicate (i.e., the predicate is fixed to check for equality or equivalence).

                Just to check: you are trying to determine if an array contains at least one non-null value, right? Because empty strings can produce the same print_r output as in your original example, and that could explain why scrupul0us made his/her suggestion.

                  laserlight;10904362 wrote:

                  scrupul0us, the empty string is not the same as null, and what Joseph Sliker wants is a way to determine if the array contains a non-null value. However, an array of nulls is not empty.

                  i know... but he asked what the resultant would be for both so i figured id cover a couple for him

                  your solution is the best way i can see to do... although if you wanted to be spiffy i suppose you could use array_walk and use a callback no?

                    Here's a one-liner, just because I could: 😉

                    function isNullArray($arr)
                    {
                       return(count(array_filter($arr, create_function('$el', 'return(!is_null($el));'))) == 0);
                    }
                    
                      NogDog;10904384 wrote:

                      Here's a one-line, just because I could: 😉

                      function isNullArray($arr)
                      {
                         return(count(array_filter($arr, create_function('$el', 'return(!is_null($el));'))) == 0);
                      }
                      

                      :rolleyes: show off

                        NogDog wrote:

                        Here's a one-liner, just because I could

                        That was my first approach, but the bad part is that array_filter() does not terminate early, and Joseph Sliker is apparently concerned about speed.

                          I'm just too thick-headed today to code the function example correctly for my use, but I believe eht following will work:

                          foreach ($NEWDATA as $id=>$taskscores)
                          {
                          $valsearch=""; //used recursively, so clear it out each time.
                          foreach($taskscores as $key=>$value) 
                          {$valsearch["$value"]=1;} //just a tally...this is just to create a key value for this variable
                          ksort($valsearch); //any null keys should not end up in the last position during the next loop.
                          foreach($valsearch as $key=>$valcount) {$tempkey="$key";} //tempkey just gets overwritten with highest key value  as long as it is empty the save script won't fire	
                          if($tempkey > "") {echo "<br>$id: there is data...run the save query";
                          //put the save query code here.
                          } else {echo "<br>$id: no score data, no save query needed.";}
                          }
                          

                          This is for an application where I am entering test scores for a classroom of kids. The submit form contains a line for each kid and a column for each test score (the first level/key of the array is the student id, the second level/key is the id of the task...and the value is the test score.

                          I just want to do this so that the script won't bother to start running the insert query for lines (kids) for which there was no data entered.

                          $NEWDATA=Array ( [1111045] => Array ( [1] => [2] => ) [1111055] => Array ( [1] => 0 [2] => 2 ) [1200020] => Array ( [1] => [2] => ) [1200025] => Array ( [1] => [2] => ) )
                          ...When it runs I get this output
                          1111045: no score data, no save query needed.
                          1111055: there is data...run the save query
                          1200020: no score data, no save query needed.
                          1200025: no score data, no save query needed.

                            laserlight;10904387 wrote:

                            That was my first approach, but the bad part is that array_filter() does not terminate early, and Joseph Sliker is apparently concerned about speed.

                            Yep, yours is faster (and probably easier to maintain, too). And your point is?

                            :p 😉

                              Another one-liner (because they're out there):

                              function contains_only_nulls($array)
                              {
                                  return count($array) == count(array_keys($array, null, true));
                              }
                              
                              laserlight wrote:

                              That was my first approach, but the bad part is that array_filter() does not terminate early, and Joseph Sliker is apparently concerned about speed.

                              Presumably there's a threshold array size (which would vary from platform to platform and version to version and all else that isn't equal) between "overhead caused by executing Zend bytecode" and "not terminating early".

                              Joseph Sliker wrote:
                              ksort($valsearch); //any null keys should not end up in the last position during the next loop.

                              Since a linear search is O(n) in the length of the array, while sorting it is going to be O(n log n) in the average case, this is probably going to waste more time than it saves (depending on all the usual overheads).

                              Though I can't help but wonder how long it would take any of the methods here to save over the others the same amount of time that this thread has occupied 🙂

                                Ooooh...the Weed meister taught me something else new. I've used array_keys() a number of times and never really noticed that 2nd parameter before.

                                  From Weedpacket:

                                  Since a linear search is O(n) in the length of the array, while sorting it is going to be O(n log n) in the average case, this is probably going to waste more time than it saves (depending on all the usual overheads).

                                  Dude, I am waaaaaaay out of my depth on that one. But thanks for trying! I'm gonna try and take off the training wheels and build/apply the functions you an lazerlight were kind enough to provide. People are asking me to do so much with my online apps now, I've got to get more efficient with code.

                                    Okay...making some progress but:

                                    Given the array:

                                    $NEWDATA=Array ( [1111045] => Array ( [1] => 0 [2] => ) [1111055] => Array ( [1] => [2] => ) [1200020] => Array ( [1] => [2] => 3 ) [1200025] => Array ( [1] => [2] => ) ) ;

                                    My scripting of the Laserlight version

                                    function contains_only_nulls_lazer($array) {
                                        foreach ($array as $value) {
                                            if (!is_null($value)) {
                                                return true;
                                            }
                                        }
                                        return false;
                                    } 
                                    
                                    foreach ($NEWDATA as $id=>$testscores)
                                    {
                                    echo "<br>$id: ".call_user_func('contains_only_nulls_lazer',$testscores)."";
                                    }

                                    Gives me this output:

                                    1111045: 1
                                    1111055: 1
                                    1200020: 1
                                    1200025: 1

                                    And the Weedpacket version:

                                    function contains_only_nulls_weedpacket($array)
                                    {
                                        return count($array) == count(array_keys($array, null, true));
                                    } 
                                    
                                    foreach ($NEWDATA as $id=>$testscores)
                                    {
                                    echo "<br>$id: ".call_user_func('contains_only_nulls_weedpacket',$testscores)."";
                                    }

                                    Gets me this:

                                    1111045:
                                    1111055:
                                    1200020:
                                    1200025:

                                    I suspect it may have something to do with my use of call_user_func ... like I say I'm not too familiar with this yet.

                                    Thanks for everyone's help so far.

                                      If I modify the weedpacket version thusly,

                                      function contains_only_nulls_weedpacket($array)
                                      {
                                          return count($array) == count(array_keys($array, '', true)); //changed null to '' (empty string)
                                      } 

                                      I now get this output which appears to be on the right track!

                                      1111045:
                                      1111055: 1
                                      1200020:
                                      1200025: 1

                                      Now I just have to figure out how to use this as a trigger for running the insert query.

                                        This seems to do the trick:

                                        //define the function
                                        function contains_only_nulls_weedpacket($array)
                                        {return count($array) == count(array_keys($array, '', true));} 
                                        
                                        
                                        //use the function
                                        foreach ($NEWDATA as $id=>$testscores)
                                        {
                                        echo "<br>$id: ";
                                        if (call_user_func('contains_only_nulls_weedpacket',$testscores)) {echo "NO SCORES";} else {echo "RUN INSERT QUERY";}
                                        }

                                        Thanks everyone!

                                          Write a Reply...