C#遍历NameValueCollection


76

我有一个NameValueCollection,并且想要遍历这些值。目前,我正在这样做,但是似乎应该有一种更整洁的方法:

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();

在那儿?


3
你有什么问题?
阿妮

2
它本身没有任何问题-只是我认为我应该能够使用单个循环进行迭代。查看到目前为止的答案,如果可能存在重复的键值,这似乎是不可能的。
Paul Michaels

没错,但是您可以使用其他收藏集,例如Dictionary<string, List<string>>
影子巫师为您而耳(

Answers:


102

您可以使用Linq展平集合,但这仍然是一个foreach循环,但现在更加隐含。

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);

第一行使用属性keyvalue将嵌套的集合转换为匿名对象的(非嵌套)集合。

它以现在是映射键->值而不是键->值集合的方式变平了。示例数据:

之前:

测试-> [Val],

Test2-> [Val1,Val1,Val2],

Test3-> [Val1],

Test4-> [Val4]

后:

测试-> Val,

Test2-> Val1,

Test2-> Val1,

Test2-> Val2,

Test3-> Val1,

Test4-> Val4


3
经过测试和使用using System.Linq;
朱利安(Julian)

3
如果有人想知道vb.net语法:Dim items = nvc.AllKeys.SelectMany(AddressOf col.GetValues, Function(k, v) New With {.key = k, .value = v})
Endy Tjahjono 2013年

2
@EndyTjahjono轻微的错字,将“ col”更改为“ nvp”,使它变成Dim items = nvc.AllKeys.SelectMany(AddressOf nvp.GetValues, Function(k, v) New With {.key = k, .value = v})
Tim Partridge


如果它是一个空白值,怎么办string.empty呢?
Si8 '18年

81

您可以使用键进行查找,而不必进行两个循环:

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

19
请注意,如果有多个值的键,这将与OP的代码不同。您的代码将输出“ key value1,value2,value3”,而OP的代码将输出“ key value1”然后是“ key value2”然后是“ key value3”
路加福音

4

这里没什么新鲜的东西(我对@Julian +1的回答在功能上是等效的),请大家一起前进。


在回答相关问题时,我有一套[对于这种情况过大但可能相关的]扩展方法,它可以让您做到:

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

3
NameValueCollection没有AsEnumerable或作为keyValuePairs
Luis Tellez

@路易斯·泰勒兹(Luis Tellez)。我知道。文字说我有一套扩展方法。它链接到它。正文指出,这里没有新内容可看。这是澄清还是我需要重新解释?
Ruben Bartelink

1

我发现避免嵌套循环的唯一方法是使用其他List来存储值:

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);

(仅需要[.NET 2.0]或更高版本)


(显然取代使用SelectMany其他答案
鲁文Bartelink

@Ruben是对的,但是即使出于历史价值显示如何使用旧.NET版本执行此操作,我还是喜欢保留此位置。:)
暗影巫师为您耳边

用的东西SelectMany我碰到是,如果密钥有的空白失败的值。有什么办法吗?谢谢。
Si8 '18年

@ Si8到底有什么失败?从理论上讲,只需抛出一条if语句并检查是否为空,尽管如果您的代码是单行代码,那么它将使代码的可读性大大降低。
暗影巫师为您耳边

您的方法可以使用null,但LINQ并非我所声明的...抱歉,不清楚。
SI 8

1

我认为这更简单:

For i As Integer = 0 To nvc.Count - 1
   Console.Write("No", "Key", "Value")
   Console.Write(i, nvc.GetKey(i), nvc.Get(i))
Next

0
var enu = myNameValueCollection.GetEnumerator();
while (enu.MoveNext())
{
    string key = (string)enu.Current;
    string value = myNameValueCollection[key];
}

或当键为空时:

for (int i = 0; i < myNameValueCollection.Count; i++)
{
    string key = myNameValueCollection.GetKey(i);
    string value = myNameValueCollection.Get(i);
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.