У меня есть множество массивов, которые будут содержать
story & message
или просто
story
Как мне проверить, содержит ли массив и историю, и сообщение? array_key_exists()
ищет только этот единственный ключ в массиве.
Есть ли способ сделать это?
array_intersect_key()
сравните массив ключей, которые вы хотите проверить, с массивом, который вы проверяете. Если длина вывода такая же, как у массива ключей для проверки, они все присутствуют.["story & message" => "value"]
или это больше похоже["story & message"]
Ответы:
Если у вас есть только 2 ключа для проверки (как в исходном вопросе), вероятно, достаточно просто
array_key_exists()
дважды позвонить, чтобы проверить, существуют ли ключи.if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) { // Both keys exist. }
Однако это явно не подходит для многих ключей. В этой ситуации поможет настраиваемая функция.
function array_keys_exists(array $keys, array $arr) { return !array_diff_key(array_flip($keys), $arr); }
источник
$keys
содержит один элемент, которого нет,$arr
а другой находится в нем,!array_diff_key
возвращает empty =>false
( пример 3v4l ) ...!array_diff($keys, array_keys($array));
потому что при их разработке требуется немного меньше когнитивной нагрузкиarray_flip
.Вот решение, которое можно масштабировать, даже если вы хотите проверить наличие большого количества ключей:
<?php // The values in this arrays contains the names of the indexes (keys) // that should exist in the data array $required = array('key1', 'key2', 'key3'); $data = array( 'key1' => 10, 'key2' => 20, 'key3' => 30, 'key4' => 40, ); if (count(array_intersect_key(array_flip($required), $data)) === count($required)) { // All required keys exist! }
источник
Удивительно
array_keys_exist
не существует ?! Тем временем это оставляет место для определения однострочного выражения для этой общей задачи. Я думаю о сценарии оболочки или другой небольшой программе.Примечание: каждое из следующих решений использует краткий
[…]
синтаксис объявления массива, доступный в php 5.4+array_diff + array_keys
if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) { // all keys found } else { // not all }
(подсказка Ким Стакс )
Это самый краткий подход, который я нашел.
array_diff()
возвращает массив элементов, присутствующих в аргументе 1, отсутствующих в аргументе 2. Следовательно, пустой массив указывает, что все ключи были найдены. В php 5.5 вы можете упростить,0 === count(…)
чтобы быть просто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 }
Сложнее читать, легко изменить.
array_reduce()
использует обратный вызов для перебора массива для получения значения. Подавая ключи мы заинтересованы в$initial
стоимости ,$in
а затем удаление ключей найдены в источнике можно ожидать до конца с 0 элементами , если были найдены все ключи.Конструкцию легко изменить, так как интересующие нас клавиши хорошо вписываются в нижнюю строку.
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 }
Проще написать, чем
array_reduce
решение, но немного сложнее отредактировать.array_filter
также является итеративным обратным вызовом, который позволяет создавать фильтрованный массив, возвращая в обратном вызове значение true (копировать элемент в новый массив) или false (не копировать). Проблема в том, что вы должны изменить2
количество предметов, которое вы ожидаете.Это можно сделать более надежным, но граничащее с абсурдной читабельностью:
$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 }
источник
Мне кажется, что самый простой способ был бы таким:
$required = array('a','b','c','d'); $values = array( 'a' => '1', 'b' => '2' ); $missing = array_diff_key(array_flip($required), $values);
Печать:
Array( [c] => 2 [d] => 3 )
Это также позволяет проверить, какие именно ключи отсутствуют. Это может быть полезно для обработки ошибок.
источник
Еще одно возможное решение:
if (!array_diff(['story', 'message'], array_keys($array))) { // OK: all the keys are in $array } else { // FAIL: some keys are not }
источник
Вышеупомянутые решения умны, но очень медленны. Простой цикл foreach с isset более чем в два раза быстрее
array_intersect_key
решения.function array_keys_exist($keys, $array){ foreach($keys as $key){ if(!array_key_exists($key, $array))return false; } return true; }
(344 мс против 768 мс для 1000000 итераций)
источник
false
( в данном случаеfalse
переопределенияtrue
). Итак, что подходит для моих нужд, так это то, чтоforeach ($keys as $key) { if (array_key_exists($key, $array)) { return true; }} return false;
мне нужно было, если быany
ключ в массиве существовал в другом массиве ...Если у вас что-то вроде этого:
$stuff = array(); $stuff[0] = array('story' => 'A story', 'message' => 'in a bottle'); $stuff[1] = array('story' => 'Foo');
Вы могли просто
count()
:foreach ($stuff as $value) { if (count($value) == 2) { // story and message } else { // only story } }
Это работает только в том случае, если вы точно знаете, что у вас есть ТОЛЬКО эти ключи массива и ничего больше.
Использование array_key_exists () поддерживает проверку только одного ключа за раз, поэтому вам нужно будет проверять оба по отдельности:
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()
возвращает истину, если ключ присутствует в массиве, но это настоящая функция, и ее нужно много набирать. Конструкция языкаisset()
будет делать почти то же самое, за исключением случая, когда проверяемое значение равно NULL:foreach ($stuff as $value) { if (isset($value['story']) && isset($value['message']) { // story and message } else { // either one or both keys missing } }
Дополнительно isset позволяет проверять сразу несколько переменных:
foreach ($stuff as $value) { if (isset($value['story'], $value['message']) { // story and message } else { // either one or both keys missing } }
Теперь, чтобы оптимизировать тест для заданного материала, вам лучше использовать это «если»:
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 } }
источник
Как насчет этого:
isset($arr['key1'], $arr['key2'])
только вернуть истину, если оба не равны нулю
если ноль, ключ отсутствует в массиве
источник
$arr['key1']
или$arr['key2']
равноnull
, код будет, ключ все еще существует.foreach
петлей?isset
функция работает так, как я имел в виду, но теперь я понимаю, что вы были правы, ключи все еще остаются в массиве, и поэтому мой ответ неверен, спасибо за отзыв. Да, я мог бы это использоватьforeach
.Я использую что-то подобное довольно часто
$wantedKeys = ['story', 'message']; $hasWantedKeys = count(array_intersect(array_keys($source), $wantedKeys)) > 0
или найти значения для желаемых ключей
$wantedValues = array_intersect_key($source, array_fill_keys($wantedKeys, 1))
источник
попробуй это
$required=['a','b'];$data=['a'=>1,'b'=>2]; if(count(array_intersect($required,array_keys($data))>0){ //a key or all keys in required exist in data }else{ //no keys found }
источник
Это функция, которую я написал для себя, чтобы использовать ее в классе.
<?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 />"; }
Я предполагаю, что вам нужно проверить наличие нескольких ключей, ВСЕ СУЩЕСТВУЮЩИХ в массиве. Если вы ищете совпадение хотя бы одного ключа, дайте мне знать, чтобы я мог предоставить другую функцию.
Кодовая панель здесь http://codepad.viper-7.com/AKVPCH
источник
if (0 === count(array_diff(['key1','key2','key3'], array_keys($lookIn)))) { // all keys exist } else { // nope }
Надеюсь это поможет:
function array_keys_exist($searchForKeys = array(), $inArray = array()) { $inArrayKeys = array_keys($inArray); return count(array_intersect($searchForKeys, $inArrayKeys)) == count($searchForKeys); }
источник
Это старый и, вероятно, будет похоронен, но это моя попытка.
У меня была проблема, похожая на @Ryan. В некоторых случаях мне нужно было только проверить, есть ли хотя бы 1 ключ в массиве, а в некоторых случаях все необходимое присутствовать.
Итак, я написал эту функцию:
/** * A key check of an array of keys * @param array $keys_to_check An array of keys to check * @param array $array_to_check The array to check against * @param bool $strict Checks that all $keys_to_check are in $array_to_check | Default: false * @return bool */ function array_keys_exist(array $keys_to_check, array $array_to_check, $strict = false) { // Results to pass back // $results = false; // If all keys are expected // if ($strict) { // Strict check // // Keys to check count // $ktc = count($keys_to_check); // Array to check count // $atc = count(array_intersect($keys_to_check, array_keys($array_to_check))); // Compare all // if ($ktc === $atc) { $results = true; } } else { // Loose check - to see if some keys exist // // Loop through all keys to check // foreach ($keys_to_check as $ktc) { // Check if key exists in array to check // if (array_key_exists($ktc, $array_to_check)) { $results = true; // We found at least one, break loop // break; } } } return $results; }
Это было намного проще , чем кратное записи
||
и&&
блоки.источник
Это не работает?
array_key_exists('story', $myarray) && array_key_exists('message', $myarray)
источник
<?php function check_keys_exists($keys_str = "", $arr = array()){ $return = false; if($keys_str != "" and !empty($arr)){ $keys = explode(',', $keys_str); if(!empty($keys)){ foreach($keys as $key){ $return = array_key_exists($key, $arr); if($return == false){ break; } } } } return $return; }
// запускаем демонстрацию
$key = 'a,b,c'; $array = array('a'=>'aaaa','b'=>'ccc','c'=>'eeeee'); var_dump( check_keys_exists($key, $array));
источник
Я не уверен, что это плохая идея, но я использую очень простой цикл foreach для проверки нескольких ключей массива.
// get post attachment source url $image = wp_get_attachment_image_src(get_post_thumbnail_id($post_id), 'single-post-thumbnail'); // read exif data $tech_info = exif_read_data($image[0]); // set require keys $keys = array('Make', 'Model'); // run loop to add post metas foreach key foreach ($keys as $key => $value) { if (array_key_exists($value, $tech_info)) { // add/update post meta update_post_meta($post_id, MPC_PREFIX . $value, $tech_info[$value]); } }
источник
// sample data $requiredKeys = ['key1', 'key2', 'key3']; $arrayToValidate = ['key1' => 1, 'key2' => 2, 'key3' => 3]; function keysExist(array $requiredKeys, array $arrayToValidate) { if ($requiredKeys === array_keys($arrayToValidate)) { return true; } return false; }
источник
$myArray = array('key1' => '', 'key2' => ''); $keys = array('key1', 'key2', 'key3'); $keyExists = count(array_intersect($keys, array_keys($myArray)));
Вернет true, потому что в $ myArray есть ключи из массива $ keys
источник
Что-то как это можно использовать
//Say given this array $array_in_use2 = ['hay' => 'come', 'message' => 'no', 'story' => 'yes']; //This gives either true or false if story and message is there count(array_intersect(['story', 'message'], array_keys($array_in_use2))) === 2;
Обновления
В одной жировой функции:
/** * Like php array_key_exists, this instead search if (one or more) keys exists in the array * @param array $needles - keys to look for in the array * @param array $haystack - the <b>Associative</b> array to search * @param bool $all - [Optional] if false then checks if some keys are found * @return bool true if the needles are found else false. <br> * Note: if hastack is multidimentional only the first layer is checked<br>, * the needles should <b>not be<b> an associative array else it returns false<br> * The array to search must be associative array too else false may be returned */ function array_keys_exists($needles, $haystack, $all = true) { $size = count($needles); if($all) return count(array_intersect($needles, array_keys($haystack))) === $size; return !empty(array_intersect($needles, array_keys($haystack))); }
Так, например, вот так:
$array_in_use2 = ['hay' => 'come', 'message' => 'no', 'story' => 'yes']; //One of them exists --> true $one_or_more_exists = array_keys_exists(['story', 'message'], $array_in_use2, false); //all of them exists --> true $all_exists = array_keys_exists(['story', 'message'], $array_in_use2);
Надеюсь это поможет :)
источник
Обычно я использую функцию для проверки моего сообщения, и это тоже ответ на этот вопрос, поэтому позвольте мне опубликовать его.
для вызова моей функции я буду использовать 2 массива, подобные этому
validatePost(['username', 'password', 'any other field'], $_POST))
тогда моя функция будет выглядеть так
function validatePost($requiredFields, $post) { $validation = []; foreach($requiredFields as $required => $key) { if(!array_key_exists($key, $post)) { $validation['required'][] = $key; } } return $validation; }
это выведет это
"обязательно": ["имя пользователя", "пароль", "любое другое поле"]
поэтому эта функция проверяет и возвращает все недостающие поля почтового запроса.
источник