Utilisation -index, il est conçu exactement pour ce cas. Comme ramanman, lorsque vous avez une liste, utilisez la liste des procédures. Avez-vous pensé à ce qui se passe si vous avez plusieurs matches?
Vous utilisez -index de 0 pour indiquer que vous êtes intéressé dans le premier index de la liste externe. -tous retourne tous les résultats. Et vous pouvez utiliser -inline si vous voulez juste la valeur de l'élément de la liste qui correspond à, de les omettre si vous voulez juste l'index de l'élément correspondant.
Si vous êtes à la recherche par le biais de la première sous-liste de chaque membre de la liste, le -index option est pour vous:
set pos [lsearch -index 0-exact $somelist "bbb"]
La -index 0 option indique à l' lsearch moteur de comparaison de prendre le premier élément de chaque élément (c'est à dire, très bien comme lindex $item 0) avant de faire d'autres opérations de comparaison (-exact comparaison dans mon exemple). Vous pouvez même fournir une liste d'indices pour descendre dans un sous-sous-liste, etc.
(NB: Ce lsearch ne pas faire est d'effectuer une recherche récursive par tous sous-liste d'une liste. Le problème est qu'il n'y a officiellement aucun moyen de savoir quand vous avez obtenu vers les feuilles.)
EDIT:
Si vous avez une vieille version de Tcl, vous pourriez ne pas avoir la -index option. Dans ce cas, vous utilisez le manuel de l'itération:
(Je n'aime pas utiliser glob de contrepartie pour ce genre de chose. Il ne fonctionne pas aussi bien quand vous êtes à la recherche d'un élément qui n'est pas le premier ni le dernier dans la liste.)
Notez que l'option d'index est introduit dans la version 8.5, donc pas disponible dans la version 8.4, qui est ce que nous avons au travail.
Ajouté la manière de le gérer. (C'est pas très élégant, ce qui est pourquoi -index a été ajouté après tout.)
set somelist {{aaa 1}{bbb 2}{ccc 1}}
lsearch -index 0 $somelist bbb;# Returns either the index if found, or -1 if not
L'index des drapeaux spécifie l'index de la sous-liste de la recherche: 0 les recherches pour aaa, bbb, ... Tout en 1 recherche 1, 2, 1...
En Tcl 8.4, utilisez le keylget commande à partir de la Tclx package:
packagerequireTclxset somelist {{aaa 1}{bbb 2}{ccc 1}}set searchTerm "bbb"if{[keylget somelist $searchTerm myvar]}{
puts "Found instance of $searchTerm, value is: $myvar"}
La keylget commande dans cette syntaxe renvoie 1 si trouvé, 0 si non. La valeur du côté de bbb (2) est placé dans la variable mavar. Notez qu'il devrait y avoir aucun signe de dollar ($) devant somelist dans le keylget commande.
Mise à jour
En fait, l'indice du pavillon permet la recherche de profondeur arbitraire, comme illustré par le présent code:
packagerequireTcl8.5# For each sub-list:# - index 0 = the user's name# - index 1 = a list of {home value}# - index 2 = a list of {id value}# - index 3 = a list of {shell value}set users {{john {home /users/john}{id 501}{shell bash}}{alex {home /users/alex}{id 502}{shell csh}}{neil {home /users/neil}{id 503}{shell zsh}}}# Search for user name == neilset term neil
puts "Search for name=$term returns: [lsearch -index 0 $users $term]";# 2# Search for user with id = 502. That means we first looks at index# 2 for {id value}, then index 1 for the valueset term 502
puts "Search for id=$term returns: [lsearch -index {2 1} $users $term]";# 1# Search for shell == sh (should return -1, not found)set term sh
puts "Search for shell=$term returns: [lsearch -index {3 1} $users $term]";# -1
Toujours mettre des accolades autour de votre if conditions; permet la compilation et de l'est (en général) plus sûr aussi.
Si vous voulez la recherche de la façon qui vous tentent, vous pouvez utiliser le glob option:
lsearch -glob $somelist "{bbb *}"
Si vous ceux sont vraiment des listes de listes, et vous êtes à la recherche pour répondre à la première sous-liste avec un premier élément de bbb vous pouvez aussi faire:
Les détails de cette dépendra bien sûr les détails de votre liste de listes (si vous n'avez que deux éléments de votre liste imbriquée, ou si elle pourrait être plus profondément imbriqués.
Le problème avec la façon dont vous le mentionner, c'est que vous dites que vous avez une liste de listes. À l'aide de lsearch est un bon moyen de listes de recherche. Mais, ensuite, à l'aide d'une chaîne de match sur les listes imbriquées apporte une variété de cas limites. En général, si vous savez que c'est une liste, utilisez la liste des opérations. Faire un générique ou glob match est une opération de chaîne. Vous pouvez sortir avec elle si vos contributions sont bien définis, mais il va revenir à vous mordre dans le cas général. Si vous connaissez un élément de la liste est une liste de, le traiter comme une liste et non pas une chaîne.
L'-glob option est par défaut pour lsearch. Et le problème était entre guillemets doubles. lsearch $somelist {bbb *} œuvres.
Utilisation -index, il est conçu exactement pour ce cas. Comme ramanman, lorsque vous avez une liste, utilisez la liste des procédures. Avez-vous pensé à ce qui se passe si vous avez plusieurs matches?
Dans votre cas, je viens de le faire:
Vous utilisez -index de 0 pour indiquer que vous êtes intéressé dans le premier index de la liste externe. -tous retourne tous les résultats. Et vous pouvez utiliser -inline si vous voulez juste la valeur de l'élément de la liste qui correspond à, de les omettre si vous voulez juste l'index de l'élément correspondant.
Si vous êtes à la recherche par le biais de la première sous-liste de chaque membre de la liste, le
-index
option est pour vous:La
-index 0
option indique à l'lsearch
moteur de comparaison de prendre le premier élément de chaque élément (c'est à dire, très bien commelindex $item 0
) avant de faire d'autres opérations de comparaison (-exact
comparaison dans mon exemple). Vous pouvez même fournir une liste d'indices pour descendre dans un sous-sous-liste, etc.(NB: Ce
lsearch
ne pas faire est d'effectuer une recherche récursive par tous sous-liste d'une liste. Le problème est qu'il n'y a officiellement aucun moyen de savoir quand vous avez obtenu vers les feuilles.)EDIT:
Si vous avez une vieille version de Tcl, vous pourriez ne pas avoir la
-index
option. Dans ce cas, vous utilisez le manuel de l'itération:(Je n'aime pas utiliser glob de contrepartie pour ce genre de chose. Il ne fonctionne pas aussi bien quand vous êtes à la recherche d'un élément qui n'est pas le premier ni le dernier dans la liste.)
-index
a été ajouté après tout.)En Tcl 8.5, mais pas dans les Tcl 8.4:
L'index des drapeaux spécifie l'index de la sous-liste de la recherche: 0 les recherches pour aaa, bbb, ... Tout en 1 recherche 1, 2, 1...
En Tcl 8.4, utilisez le keylget commande à partir de la Tclx package:
La keylget commande dans cette syntaxe renvoie 1 si trouvé, 0 si non. La valeur du côté de bbb (2) est placé dans la variable mavar. Notez qu'il devrait y avoir aucun signe de dollar ($) devant somelist dans le keylget commande.
Mise à jour
En fait, l'indice du pavillon permet la recherche de profondeur arbitraire, comme illustré par le présent code:
if
conditions; permet la compilation et de l'est (en général) plus sûr aussi.Utiliser la fonction "index" option de [lsearch].
Si vous voulez la recherche de la façon qui vous tentent, vous pouvez utiliser le glob option:
Si vous ceux sont vraiment des listes de listes, et vous êtes à la recherche pour répondre à la première sous-liste avec un premier élément de bbb vous pouvez aussi faire:
Les détails de cette dépendra bien sûr les détails de votre liste de listes (si vous n'avez que deux éléments de votre liste imbriquée, ou si elle pourrait être plus profondément imbriqués.
lsearch $somelist {bbb *}
œuvres.