Pour tous les peuples du temps, une fois pour toutes.
Il y a un long chemin de "code propre", et il y a un chemin plus court, plus concis, centré sur bash.
$1
= L'index ou la clé que vous recherchez.
$2
= Le tableau / la carte transmis par référence .
function hasKey ()
{
local -r needle="${1:?}"
local -nr haystack=${2:?}
for key in "${!haystack[@]}"; do
if [[ $key == $needle ]] ;
return 0
fi
done
return 1
}
Une recherche linéaire peut être remplacée par une recherche binaire, qui serait plus performante avec des ensembles de données plus importants. Il suffit de compter et de trier les clés dans un premier temps, puis de diviser la meule de foin en deux de manière binaire au fur et à mesure que l'on se rapproche de la réponse.
Maintenant, pour les puristes qui se disent "Non, je veux la version la plus performante parce que je pourrais avoir à gérer de grands tableaux en bash", voyons une solution plus centrée sur bash, mais qui conserve un code propre et la flexibilité de gérer des tableaux ou des cartes.
function hasKey ()
{
local -r needle="${1:?}"
local -nr haystack=${2:?}
[ -n ${haystack["$needle"]+found} ]
}
La línea [ -n ${haystack["$needle"]+found} ]
utilise le ${parameter+word}
de l'expansion des variables de bash, et non la ${parameter:+word}
qui tente également de tester la valeur d'une clé, ce qui n'est pas le sujet du jour .
Utilisation
local -A person=(firstname Anthony lastname Rutledge)
if hasMapKey "firstname" person; then
# Do something
fi
Lorsqu'on n'effectue pas d'expansion de sous-chaîne, en utilisant la forme décrite (par exemple, ':-'), Bash teste un paramètre qui n'est pas défini ou qui est nul. L'omission des deux points entraîne un test uniquement pour un paramètre qui est non défini. En d'autres termes, si les deux points sont inclus, l'opérateur teste à la fois l'existence du paramètre et le fait que le paramètre est nul. l'existence des deux paramètres et que leur valeur n'est pas nulle ; si le signe deux-points est omis, l'opérateur ne teste que l'existence.
${paramètre:-mot}
If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
${paramètre:=mot}
If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional
Les paramètres et les paramètres spéciaux ne peuvent pas être affectés de cette manière. ${paramètre:?mot}
If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard
et le shell, s'il n'est pas interactif, quitte. Sinon, la valeur valeur du paramètre est substituée. ${paramètre:+mot}
If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion
Si $needle
n'existe pas, sinon il est développé en une chaîne de longueur non nulle, "found". Cela rendra le -n
réussissent si le test $needle
existe en fait (comme je dis "trouvé"), et échoue dans le cas contraire.