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.

3
  • @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. Commented May 30, 2022 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. Commented May 30, 2022 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 :) Commented May 30, 2022 at 11:17

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

3 Comments

empty() is an unnecessary function call if the value passed to the function is guaranteed to exist. ! will do.
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.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.