tags:

views:

124

answers:

4

I have an if statement that needs to check if a series of items exist AND if any other items exist.

So for example

foreach($id_cart as $id) {
if(($id == 4 || $id == 5) && **IF ANY OTHER ITEM EXISTS**){
    echo "Yes";
}

Is there a simple way of doing that? An item exists or it does not. $id_cart will have, let's say, ids: 4,5,6,8,12,14 There is nothing else stored. So if 4 or 5 are there, plus any other number...

+1  A: 

this will find items which are not 4 or 5

$others = array_diff($id_cart, array(4, 5));

this will find items whose keys are not 4 or 5

$others = array_diff_key($id_cart, array_flip(array(4, 5)));
stereofrog
A: 

An efficient way is to store the ID's in the array's keys and check for their existence with isset().

PHP's arrays are dictionaries. Take advantage of this feature, instead of wasting time with in_array().

Dor
See also http://php.net/array_flip
Bill Karwin
+4  A: 

If your question is asking "I have a list of ids, from which I want to know if one is there, and apart of that one, if other items exist", one course of action could be the following:

  • if the item you look for exists, remove it from the array and check if it still has any members
    • if count(array) is > 0 do this; else do that;
  • else wasn't there or was 'alone'.

This course of action is very optimizable: for instance, your original array would lose members at each iteration. One easy change would be just do count(array) - 1 if you don't care which members the array contains.

Perhaps this does what you want:

foreach ($id_cart as $id) {
    if (($id == 4 || $id == 5) && count(array_diff($id_cart, array(4, 5)))) {
        // do something
    }
}

or, better:

if ((in_array(4, $id_cart) || in_array(5, $id_cart)) && count(array_diff($id_cart, array(4, 5)))) {
   // four or five exists, while other elements are also in the array
   // do something
}
Adriano Varoli Piazza
Last lot of code is good.
Blair McMillan
+4  A: 
<?php

$a = array(4, 5);
if (array_intersect($id_cart, $a) && array_diff($id_cart, $a))
{
    echo "Yes\n";
} else {
    echo "No\n";
}

Tested:

  • 4,5: No
  • 4,6: Yes
  • 5,6: Yes
  • 6,8: No
  • 4,5,6,8,12,14: Yes

See array_intersect() and array_diff().

Intersect with array(4,5) tests for presence of either 4 or 5, because the result would be empty if neither value occurred in $id_cart.

Diff with array(4,5) tests for presence of another value besides 4 and 5, because the result would be empty if no value but 4 or 5 occurred in $id_cart.

Using count() to test for a non-empty array is unnecessary. An empty array evaluates as false in a condition.


Re Adriano's comment about simplicity or efficiency: PHP is tricky this way. Some functions are more efficient than others, so it's hard to say 2 function calls is better than 3. I tried running both my solution and Adriano's, and measuring elapsed time using microtime():

  • Bill's solution: 6.25 seconds for 100000 iterations
  • Adriano's solution: 5.59 seconds for 100000 iterations

So they're not equal, but Adriano's is only 10.5% faster. Close enough that I'd choose a solution for readability instead of for performance. If optimal performance were one's highest priority, one wouldn't be using PHP in the first place. :-)

FWIW, Adriano's other solution using foreach took 7.13 seconds for 100000 iterations.

Bill Karwin
two function calls instead of (possibly) 3 as in my case, good. And the code is still self-documenting. Though I'd create a variable to represent array(4, 5).
Adriano Varoli Piazza
Good call on using an array variable. It did speed up both solutions a bit in my test. I'll edit my post above.
Bill Karwin