77 votes

C# Iterate through NameValueCollection (Interroger une collection de valeurs de noms)

J'ai un NameValueCollection et que l'on souhaite itérer à travers les valeurs. C'est ce que je fais actuellement, mais il me semble qu'il devrait y avoir un moyen plus propre de le faire :

NameValueCollection nvc = new NameValueCollection();
nvc.Add("Test", "Val1");
nvc.Add("Test2", "Val1");
nvc.Add("Test2", "Val1");
nvc.Add("Test2", "Val2");
nvc.Add("Test3", "Val1");
nvc.Add("Test4", "Val4");

foreach (string s in nvc)
    foreach (string v in nvc.GetValues(s))
        Console.WriteLine("{0} {1}", s, v);

Console.ReadLine();

Existe-t-il ?

3 votes

Qu'est-ce qui ne va pas avec ce que vous avez ?

2 votes

Il n'y a rien de mal à cela en soi - je pensais simplement que je devrais pouvoir itérer en utilisant une seule boucle. En regardant les réponses jusqu'à présent, cela ne semble pas être possible s'il y a des valeurs de clé en double.

0 votes

C'est exact, mais vous pouvez utiliser une collection différente, par exemple Dictionary<string, List<string>>

110voto

Julian Points 972

Vous pouvez aplatir la collection avec Linq, mais il s'agit toujours d'une collection de type foreach mais désormais plus implicite.

var items = nvc.AllKeys.SelectMany(nvc.GetValues, (k, v) => new {key = k, value = v});
foreach (var item in items)
    Console.WriteLine("{0} {1}", item.key, item.value);

La première ligne convertit la collection imbriquée en une collection (non imbriquée) d'objets anonymes ayant les propriétés suivantes clé y valeur .

Il est aplati dans la mesure où il s'agit désormais d'une cartographie. clé -> valeur au lieu de clé -> collection de valeurs . Les données de l'exemple :

Avant :

Test -> [Val],

Test2 -> [Val1, Val1, Val2],

Test3 -> [Val1],

Test4 -> [Val4]

Après :

Test -> Val,

Test2 -> Val1,

Test2 -> Val1,

Test2 -> Val2,

Test3 -> Val1,

Test4 -> Val4

3 votes

Testé et utilisé using System.Linq;

3 votes

Au cas où quelqu'un voudrait connaître la syntaxe vb.net : Dim items = nvc.AllKeys.SelectMany(AddressOf col.GetValues, Function(k, v) New With {.key = k, .value = v})

2 votes

@EndyTjahjono petite faute de frappe, remplacer "col" par "nvp" pour que cela devienne Dim items = nvc.AllKeys.SelectMany(AddressOf nvp.GetValues, Function(k, v) New With {.key = k, .value = v})

88voto

Fredrik Mörk Points 85694

Vous pouvez utiliser la clé pour la recherche au lieu d'avoir deux boucles :

foreach (string key in nvc)
{
    Console.WriteLine("{0} {1}", key, nvc[key]);
}

19 votes

Notez que ce code se comportera différemment de celui de l'OP s'il y a des clés avec des valeurs multiples. Votre code produira "clé valeur1,valeur2,valeur3" alors que le code du PO produirait "clé valeur1" puis "clé valeur2 puis "clé valeur3" .

4voto

Ruben Bartelink Points 23945

Rien de nouveau à voir ici (la réponse +1 de @Julian est fonctionnellement équivalente), passez votre chemin s'il vous plaît.


J'ai un ensemble de méthodes d'extension [excessif pour ce cas, mais peut-être pertinent]. dans une réponse à une question connexe qui vous permettrait de le faire :

foreach ( KeyValuePair<string,string> item in nvc.AsEnumerable().AsKeyValuePairs() )
    Console.WriteLine("{0} {1}", item.key, item.value);

3 votes

NameValueCollection ne dispose pas de AsEnumerable ou de as keyValuePairs

0 votes

@Luis Tellez. Je sais. Le texte dit J'ai un ensemble de méthodes d'extension . Et il établit un lien avec lui. Et le corps du texte signale qu'il n'y a rien de nouveau à voir ici, s'il vous plaît. Est-ce que cela est clair ou dois-je réexpliquer ?

0 votes

Vous pouvez rendre un énumérable comme IEnumerable<KeyValuePair<string,string>> e = nvc.AllKeys.Select(k => new KeyValuePair<string, string>(k, nvc[k])) . Un autre point d'achoppement apporté par Microsoft.

1voto

Shadow Wizard Points 38568

Le seul moyen que j'ai trouvé pour éviter les boucles imbriquées est d'utiliser une liste supplémentaire pour stocker les valeurs :

List<string> arrValues = new List<string>();
for (int i = 0; i < nvc.Count; i++)
    arrValues.AddRange(nvc.GetValues(i));
foreach (string value in arrValues)
    Console.WriteLine(value);

(Nécessite [uniquement] .NET 2.0 ou une version ultérieure)

0 votes

(évidemment remplacée par l'utilisation de SelectMany comme l'autre réponse )

0 votes

@Ruben c'est vrai, mais je préfère laisser celui-ci même si c'est juste pour la valeur historique montrant comment faire cela avec une ancienne version de .NET :)

0 votes

Le problème avec SelectMany J'ai constaté que si la clé a une valeur vide, l'opération échoue. Comment contourner ce problème ? Merci de votre compréhension.

-2voto

Sachin Shanbhag Points 20979
foreach ( string key in nvc.Keys )
   Console.WriteLine("{0} {1}", key, nvc[key]);

Vous obtiendrez ainsi toutes les clés et les valeurs correspondantes.

2 votes

Non, il ne renverra pas de valeurs dupliquées.

0 votes

Ne s'agit-il pas d'un doublon de stackoverflow.com/a/5065986/11635 ce qui est quelques millisecondes plus tôt (wow !) - personnellement je supprimerais. @Slaks pour être pédant, il donnera les valeurs dupliquées, mais en les séparant par des virgules.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X