How to check if multiple array keys exists

2019-01-29 23:01发布

I have a variety of arrays that will either contain

story & message

or just

story

How would I check to see if an array contains both story and message? array_key_exists() only looks for that single key in the array.

Is there a way to do this?

标签: php key
18条回答
孤傲高冷的网名
2楼-- · 2019-01-29 23:23

Surprisingly array_keys_exist doesn't exist?! In the interim that leaves some space to figure out a single line expression for this common task. I'm thinking of a shell script or another small program.

Note: each of the following solutions use concise […] array declaration syntax available in php 5.4+

array_diff + array_keys

if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) {
  // all keys found
} else {
  // not all
}

(hat tip to Kim Stacks)

This approach is the most brief I've found. array_diff() returns an array of items present in argument 1 not present in argument2. Therefore an empty array indicates all keys were found. In php 5.5 you could simplify 0 === count(…) to be simply empty(…).

array_reduce + unset

if (0 === count(array_reduce(array_keys($source), 
    function($in, $key){ unset($in[array_search($key, $in)]); return $in; }, 
    ['story', 'message', '…'])))
{
  // all keys found
} else {
  // not all
}

Harder to read, easy to change. array_reduce() uses a callback to iterate over an array to arrive at a value. By feeding the keys we're interested in the $initial value of $in and then removing keys found in source we can expect to end with 0 elements if all keys were found.

The construction is easy to modify since the keys we're interested in fit nicely on the bottom line.

array_filter & in_array

if (2 === count(array_filter(array_keys($source), function($key) { 
        return in_array($key, ['story', 'message']); }
    )))
{
  // all keys found
} else {
  // not all
}

Simpler to write than the array_reduce solution but slightly tricker to edit. array_filter is also an iterative callback that allows you to create a filtered array by returning true (copy item to new array) or false (don't copy) in the callback. The gotchya is that you must change 2 to the number of items you expect.

This can be made more durable but verge's on preposterous readability:

$find = ['story', 'message'];
if (count($find) === count(array_filter(array_keys($source), function($key) use ($find) { return in_array($key, $find); })))
{
  // all keys found
} else {
  // not all
}
查看更多
仙女界的扛把子
3楼-- · 2019-01-29 23:23

If you have something like this:

$stuff = array();
$stuff[0] = array('story' => 'A story', 'message' => 'in a bottle');
$stuff[1] = array('story' => 'Foo');

You could simply count():

foreach ($stuff as $value) {
  if (count($value) == 2) {
    // story and message
  } else {
    // only story
  }
}

This only works if you know for sure that you ONLY have these array keys, and nothing else.

Using array_key_exists() only supports checking one key at a time, so you will need to check both seperately:

foreach ($stuff as $value) {
  if (array_key_exists('story', $value) && array_key_exists('message', $value) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

array_key_exists() returns true if the key is present in the array, but it is a real function and a lot to type. The language construct isset() will almost do the same, except if the tested value is NULL:

foreach ($stuff as $value) {
  if (isset($value['story']) && isset($value['message']) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

Additionally isset allows to check multiple variables at once:

foreach ($stuff as $value) {
  if (isset($value['story'], $value['message']) {
    // story and message
  } else {
    // either one or both keys missing
  }
}

Now, to optimize the test for stuff that is set, you'd better use this "if":

foreach ($stuff as $value) {
  if (isset($value['story']) {
    if (isset($value['message']) {
      // story and message
    } else {
      // only story
    }
  } else {
    // No story - but message not checked
  }
}
查看更多
Ridiculous、
4楼-- · 2019-01-29 23:32

It seems to me, that the easiest method by far would be this:

$required = array('a','b','c','d');

$values = array(
    'a' => '1',
    'b' => '2'
);

$missing = array_diff_key(array_flip($required), $values);

Prints:

Array(
    [c] => 2
    [d] => 3
)

This also allows to check which keys are missing exactly. This might be useful for error handling.

查看更多
老娘就宠你
5楼-- · 2019-01-29 23:33
$myArray = array('key1' => '', 'key2' => '');
$keys = array('key1', 'key2', 'key3');
$keyExists = count(array_intersect($keys, array_keys($myArray)));

Will return true, because there are keys from $keys array in $myArray

查看更多
仙女界的扛把子
6楼-- · 2019-01-29 23:34

Hope this helps:

function array_keys_exist($searchForKeys = array(), $inArray = array()) {
    $inArrayKeys = array_keys($inArray);
    return count(array_intersect($searchForKeys, $inArrayKeys)) == count($searchForKeys); 
}
查看更多
贪生不怕死
7楼-- · 2019-01-29 23:36

This is the function I wrote for myself to use within a class.

<?php
/**
 * Check the keys of an array against a list of values. Returns true if all values in the list
 is not in the array as a key. Returns false otherwise.
 *
 * @param $array Associative array with keys and values
 * @param $mustHaveKeys Array whose values contain the keys that MUST exist in $array
 * @param &$missingKeys Array. Pass by reference. An array of the missing keys in $array as string values.
 * @return Boolean. Return true only if all the values in $mustHaveKeys appear in $array as keys.
 */
    function checkIfKeysExist($array, $mustHaveKeys, &$missingKeys = array()) {
        // extract the keys of $array as an array
        $keys = array_keys($array);
        // ensure the keys we look for are unique
        $mustHaveKeys = array_unique($mustHaveKeys);
        // $missingKeys = $mustHaveKeys - $keys
        // we expect $missingKeys to be empty if all goes well
        $missingKeys = array_diff($mustHaveKeys, $keys);
        return empty($missingKeys);
    }


$arrayHasStoryAsKey = array('story' => 'some value', 'some other key' => 'some other value');
$arrayHasMessageAsKey = array('message' => 'some value', 'some other key' => 'some other value');
$arrayHasStoryMessageAsKey = array('story' => 'some value', 'message' => 'some value','some other key' => 'some other value');
$arrayHasNone = array('xxx' => 'some value', 'some other key' => 'some other value');

$keys = array('story', 'message');
if (checkIfKeysExist($arrayHasStoryAsKey, $keys)) { // return false
    echo "arrayHasStoryAsKey has all the keys<br />";
} else {
    echo "arrayHasStoryAsKey does NOT have all the keys<br />";
}

if (checkIfKeysExist($arrayHasMessageAsKey, $keys)) { // return false
    echo "arrayHasMessageAsKey has all the keys<br />";
} else {
    echo "arrayHasMessageAsKey does NOT have all the keys<br />";
}

if (checkIfKeysExist($arrayHasStoryMessageAsKey, $keys)) { // return false
    echo "arrayHasStoryMessageAsKey has all the keys<br />";
} else {
    echo "arrayHasStoryMessageAsKey does NOT have all the keys<br />";
}

if (checkIfKeysExist($arrayHasNone, $keys)) { // return false
    echo "arrayHasNone has all the keys<br />";
} else {
    echo "arrayHasNone does NOT have all the keys<br />";
}

I am assuming you need to check for multiple keys ALL EXIST in an array. If you are looking for a match of at least one key, let me know so I can provide another function.

Codepad here http://codepad.viper-7.com/AKVPCH

查看更多
登录 后发表回答