1

I'm trying to verify if certain values exist within an array excluding a specific key:

$haystack = array(
    "id" => 1,
    "char1" => 2,
    "char2" => 3,
    "char3" => 4,
);

$needles = array(2, 4);

Solution that I found here: in_array multiple values

function in_array_all($needles, $haystack) {
    return empty(array_diff($needles, $haystack));
}

The problem is that I'm checking if certain chars exist within the array. This will work fine in this case:

$exists = in_array_all([2, 4], $haystack); // true

But it'll cause an issue in this situation:

$exists = in_array_all([1, 3], $haystack); // true

It found the value 1 in the key id and therefor evaluates as true while a char with id 1 is not within the array. How can I make it so that it excludes the key id within the search?

Note: This is example data. The real data is much larger, so just using if / else statements isn't really viable.

icecub
  • 8,615
  • 6
  • 41
  • 70
  • @icecub performance wise mine is better than what they're doing. Mine only runs on each key in the array rather than running on each needle and then on each key in the array. Basically my method only runs once whereas his solution does the same thing for every needle. – Zei May 30 '22 at 11:03
  • @rid If you look at my first comment, the unset answer is what I recommended. However, it's definitely not the right answer here. You may want to include more data to pass over than just the ID key, in which case storing in separate variables and unsetting them is not good practice. You're best off not modifying the original array. The performance difference in this case is negligible. – Zei May 30 '22 at 11:09
  • @Zei You're correct. Guess performance wise it won't make a difference since PHP makes a copy and doesn't use a reference anyway. Just a lot less code needed. Thanks a lot for your help and teaching a few things though :) – icecub May 30 '22 at 11:17

2 Answers2

2
function in_array_all($needles, $haystack) {
    return empty(array_diff($needles, $haystack));
}

function excludeKeys($haystack){
    $tempArray = array();
    foreach($haystack as $key => $value){
        if ($key == "id"){
            // Don't include
        }else{
            $tempArray[$key] = $value;
        }
    }
    return $tempArray;
}

$haystack = array(
    "id" => 1,
    "char1" => 2,
    "char2" => 3,
    "char3" => 4,
);

$exists = in_array_all([1, 3], excludeKeys($haystack));

echo("Exists: ".($exists ? "Yes" : "No"));

This basically just returns the array without the keys you specify. This keeps the original array in tact for later use.

Edit:

These bad solutions are really a symptom of a problem in your data structure. You should consider converting your array to an object. It looks like this:

$object = new stdClass();
$object->id = 1;
$object->chars = array(2, 3, 4);

$exists = in_array_all([1, 3], $object->chars);

This is how you're supposed to separate your data up. This way you can properly store your information by key. Furthermore you can store other objects or arrays within the object specific to a key, as shown above.

Zei
  • 409
  • 5
  • 14
1

Unset id index and then do search:

function in_array_any($needles, $haystack) {
    unset($haystack['id']);
    return !array_diff($needles, $haystack);
}

https://3v4l.org/PTjOS

Alive to die - Anant
  • 70,531
  • 10
  • 51
  • 98
  • `empty()` is an unnecessary function call if the value passed to the function is guaranteed to exist. `!` will do. – mickmackusa May 31 '22 at 05:12
  • If @icecub's requirement is that BOTH needles exist in the qualifying values of the haystack then this answer is incorrect (and the function name is appropriate). If only one of the two needles needs to be found, then this solution is correct, but arguably inefficient (and the function name should be `in_array_any()`). I find the question requirements to be ambiguous. – mickmackusa May 31 '22 at 05:19
  • I'll give icecub some time to respond and potentially update the question. Otherwise, it is very easy to hammer this question with any page that explains how to unset an array element. – mickmackusa May 31 '22 at 05:45