J'ai une variété de tableaux qui contiendront soit
story & message
ou juste
story
Comment vérifier si un tableau contient à la fois une histoire et un message? array_key_exists()
recherche uniquement cette clé unique dans le tableau.
Y a-t-il un moyen de faire cela?
array_intersect_key()
comparer un tableau des clés que vous souhaitez vérifier avec le tableau que vous vérifiez. Si la longueur de la sortie est la même que le tableau de clés à vérifier, elles sont toutes présentes.["story & message" => "value"]
est-il au format ou est-il plus semblable à["story & message"]
Réponses:
Si vous n'avez que 2 clés à vérifier (comme dans la question d'origine), il est probablement assez facile d'appeler
array_key_exists()
deux fois pour vérifier si les clés existent.if (array_key_exists("story", $arr) && array_key_exists("message", $arr)) { // Both keys exist. }
Cependant, cela ne s'adapte évidemment pas bien à de nombreuses clés. Dans cette situation, une fonction personnalisée aiderait.
function array_keys_exists(array $keys, array $arr) { return !array_diff_key(array_flip($keys), $arr); }
la source
$keys
contient un élément qui n'est pas$arr
dedans et un autre qui y est,!array_diff_key
renvoie vide =>false
( exemple 3v4l ) ...!array_diff($keys, array_keys($array));
car il y a un peu moins de charge cognitive impliquée dans l'élaboration de cesarray_flip
s.Voici une solution évolutive, même si vous souhaitez rechercher un grand nombre de clés:
<?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! }
la source
Étonnamment
array_keys_exist
n'existe pas?! En attendant, cela laisse un peu d'espace pour trouver une expression sur une seule ligne pour cette tâche courante. Je pense à un script shell ou à un autre petit programme.Remarque: chacune des solutions suivantes utilise la
[…]
syntaxe de déclaration de tableau concise disponible dans php 5.4+array_diff + array_keys
if (0 === count(array_diff(['story', 'message', '…'], array_keys($source)))) { // all keys found } else { // not all }
(pointe du chapeau à Kim Stacks )
Cette approche est la plus brève que j'ai trouvée.
array_diff()
renvoie un tableau d'éléments présents dans l'argument 1 non présents dans l'argument2. Par conséquent, un tableau vide indique que toutes les clés ont été trouvées. En php 5.5, vous pourriez simplifier0 === count(…)
pour être simplementempty(…)
.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 }
Plus difficile à lire, facile à changer.
array_reduce()
utilise un rappel pour parcourir un tableau pour arriver à une valeur. En alimentant les clés, nous nous intéressons à la$initial
valeur de$in
, puis en supprimant les clés trouvées dans la source, nous pouvons nous attendre à terminer avec 0 élément si toutes les clés ont été trouvées.La construction est facile à modifier car les clés qui nous intéressent s'adaptent bien à la ligne du bas.
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 }
Plus simple à écrire que la
array_reduce
solution mais légèrement plus compliqué à modifier.array_filter
est également un rappel itératif qui vous permet de créer un tableau filtré en retournant true (copier l'élément dans un nouveau tableau) ou false (ne pas copier) dans le rappel. Le gotchya est que vous devez changer2
le nombre d'articles que vous attendez.Cela peut être rendu plus durable mais à la limite de la lisibilité absurde:
$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 }
la source
Il me semble que la méthode la plus simple serait de loin la suivante:
$required = array('a','b','c','d'); $values = array( 'a' => '1', 'b' => '2' ); $missing = array_diff_key(array_flip($required), $values);
Impressions:
Array( [c] => 2 [d] => 3 )
Cela permet également de vérifier quelles clés manquent exactement. Cela peut être utile pour la gestion des erreurs.
la source
Une autre solution possible:
if (!array_diff(['story', 'message'], array_keys($array))) { // OK: all the keys are in $array } else { // FAIL: some keys are not }
la source
Les solutions ci-dessus sont intelligentes, mais très lentes. Une simple boucle foreach avec isset est plus de deux fois plus rapide que la
array_intersect_key
solution.function array_keys_exist($keys, $array){ foreach($keys as $key){ if(!array_key_exists($key, $array))return false; } return true; }
(344 ms contre 768 ms pour 1000000 itérations)
la source
false
(false
remplacetrue
dans ce cas). Donc, ce qui fonctionne pour mes besoins, c'est queforeach ($keys as $key) { if (array_key_exists($key, $array)) { return true; }} return false;
mes besoins étaient si laany
clé d'un tableau existe dans un autre tableau ...Si vous avez quelque chose comme ça:
$stuff = array(); $stuff[0] = array('story' => 'A story', 'message' => 'in a bottle'); $stuff[1] = array('story' => 'Foo');
Vous pouvez simplement
count()
:foreach ($stuff as $value) { if (count($value) == 2) { // story and message } else { // only story } }
Cela ne fonctionne que si vous savez avec certitude que vous avez UNIQUEMENT ces clés de tableau, et rien d'autre.
L'utilisation de array_key_exists () ne prend en charge que la vérification d'une clé à la fois, vous devrez donc vérifier les deux séparément:
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()
renvoie true si la clé est présente dans le tableau, mais c'est une fonction réelle et beaucoup à taper. La construction du langageisset()
fera presque la même chose, sauf si la valeur testée est NULL:foreach ($stuff as $value) { if (isset($value['story']) && isset($value['message']) { // story and message } else { // either one or both keys missing } }
De plus, isset permet de vérifier plusieurs variables à la fois:
foreach ($stuff as $value) { if (isset($value['story'], $value['message']) { // story and message } else { // either one or both keys missing } }
Maintenant, pour optimiser le test des éléments définis, vous feriez mieux d'utiliser ce "si":
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 } }
la source
Et ça:
isset($arr['key1'], $arr['key2'])
ne renvoie true que si les deux ne sont pas nuls
si est nul, la clé n'est pas dans le tableau
la source
$arr['key1']
ou$arr['key2']
estnull
, le code sera, la clé existe toujours.foreach
boucle?isset
fonction fonctionne comme je l'entendais, mais maintenant je réalise que vous aviez raison, les clés restent toujours dans un tableau et donc ma réponse n'est pas correcte, merci pour vos commentaires. Oui, je pourrais l'utiliserforeach
.J'utilise quelque chose comme ça assez souvent
$wantedKeys = ['story', 'message']; $hasWantedKeys = count(array_intersect(array_keys($source), $wantedKeys)) > 0
ou pour trouver les valeurs des clés recherchées
$wantedValues = array_intersect_key($source, array_fill_keys($wantedKeys, 1))
la source
essaye ça
$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 }
la source
C'est la fonction que j'ai écrite pour moi-même à utiliser dans une classe.
<?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 />"; }
Je suppose que vous devez vérifier plusieurs clés TOUTES EXISTENT dans un tableau. Si vous recherchez une correspondance d'au moins une clé, faites-le moi savoir afin que je puisse fournir une autre fonction.
Codepad ici http://codepad.viper-7.com/AKVPCH
la source
if (0 === count(array_diff(['key1','key2','key3'], array_keys($lookIn)))) { // all keys exist } else { // nope }
J'espère que cela t'aides:
function array_keys_exist($searchForKeys = array(), $inArray = array()) { $inArrayKeys = array_keys($inArray); return count(array_intersect($searchForKeys, $inArrayKeys)) == count($searchForKeys); }
la source
Ceci est vieux et sera probablement enterré, mais c'est ma tentative.
J'ai eu un problème similaire à @Ryan. Dans certains cas, je devais vérifier uniquement si au moins 1 clé était dans un tableau, et dans certains cas, tout était nécessaire être présentes.
J'ai donc écrit cette fonction:
/** * 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; }
C'était beaucoup plus facile que d'avoir à écrire plusieurs blocs
||
et&&
.la source
Cela ne marche pas?
array_key_exists('story', $myarray) && array_key_exists('message', $myarray)
la source
<?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; }
// lancer la démo
$key = 'a,b,c'; $array = array('a'=>'aaaa','b'=>'ccc','c'=>'eeeee'); var_dump( check_keys_exists($key, $array));
la source
Je ne suis pas sûr, si c'est une mauvaise idée, mais j'utilise une boucle foreach très simple pour vérifier plusieurs clés de tableau.
// 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]); } }
la source
// 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; }
la source
$myArray = array('key1' => '', 'key2' => ''); $keys = array('key1', 'key2', 'key3'); $keyExists = count(array_intersect($keys, array_keys($myArray)));
Renvoie true, car il y a des clés du tableau $ keys dans $ myArray
la source
Quelque chose comme cela pourrait être utilisé
//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;
Mises à jour
Dans une fonction de graisse :
/** * 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))); }
Donc par exemple avec ceci:
$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);
J'espère que cela t'aides :)
la source
J'utilise généralement une fonction pour valider mon message et c'est aussi une réponse à cette question, alors laissez-moi le poster.
pour appeler ma fonction, j'utiliserai le tableau 2 comme ceci
validatePost(['username', 'password', 'any other field'], $_POST))
alors ma fonction ressemblera à ceci
function validatePost($requiredFields, $post) { $validation = []; foreach($requiredFields as $required => $key) { if(!array_key_exists($key, $post)) { $validation['required'][] = $key; } } return $validation; }
cela affichera ceci
"obligatoire": ["nom d'utilisateur", "mot de passe", "tout autre champ"]
donc ce que fait cette fonction est de valider et de renvoyer tous les champs manquants de la demande de publication.
la source