C#LINQ查询/从FormCollection投影
问题描述:
我有一个动态的形式,我不能使用MVC的绑定。当我张贴此的FormCollection到我的控制器,简化的,我有如下形式收集以下数据:C#LINQ查询/从FormCollection投影
public ActionResult Foo(FormCollection coll)
...
coll["Data0Key"] contains "category"
coll["Data0Value"] contains "123"
coll["Data1Key"] contains "location"
coll["Data1Value"] contains "21"
coll["Data7Key"] contains "area"
coll["Data7Value"] contains "test"
coll["SomethingElse"] contains "irrelevent"
..我有数目不详的这些,并想从单独的键创建键值对并在集合中的值对象
我一直在尝试沿着;
var settings = coll.AllKeys
.Where(k => k.StartsWith("Data"))
.ToDictionary(k => k, k => coll[k]);
,给了我的字典:
Data0Key, category
Data0Value, 123
Data1Key, location
Data1Value, 21
Data7Key, area
Data7Value, test
我真的想拥有的是结构类似的键值对的集合;
category, 123
location, 21
area, test
是我试图实现的可能性,还是我需要找到不同的方法?
答
我想你只想迭代“DataxKey”部分,然后查找值。喜欢的东西:
.Where(k => k.StartsWith("Data") && k.EndsWith("Key"))
.ToDictionary(k => coll[k], k => coll[k.Replace("Key", "Value")]);
这是假设每一个“Data0Key”中也有“Data0Value”对匹配,否则它会提领不从coll
存在的关键。
答
这可以用相对简单的LINQ查询来完成:
var data = new Dictionary<string,object> {
["Data0Key"] = "category"
, ["Data0Value"] = "123"
, ["Data1Key"] = "location"
, ["Data1Value"] = "21"
, ["Data7Key"] = "area"
, ["Data7Value"] = "test"
, ["SomethingElse"] = "irrelevent"
};
var kvp = data
.Where(p => p.Key.StartsWith("Data") && (p.Key.EndsWith("Key") || p.Key.EndsWith("Value")))
.Select(p => new {
Key = p.Key.Substring(0, p.Key.Length - (p.Key.EndsWith("Key") ? 3 : 5))
, IsKey = p.Key.EndsWith("Key")
, p.Value
})
.GroupBy(p => p.Key)
.Where(g => g.Count(p => p.IsKey) == 1 && g.Count(p => !p.IsKey) == 1)
.ToDictionary(g => (string)g.Single(p => p.IsKey).Value, g => g.Single(p => !p.IsKey).Value);
foreach (var p in kvp) {
Console.WriteLine("{0} - {1}", p.Key, p.Value);
}
这里是什么做一行一行地解释:
- 首先,无关的项目被过滤掉确保只保留
"Data"
前缀,后缀为"Key"
或"Value"
- 接下来,通过删除
"Key"
或来提取组密钥后缀;所述Value
被添加到列表中,与表示如果一个项目是 - 每个组进行检查,以精确地包含一个键或一个值
- 的项目是由组密钥分组(
"Data0"
,"Data7"
等)IsKey
标志一起一个关键和一个价值;丢弃不完整的组 - 最后,将组转换为键值对的字典。
字典与键值对的集合有什么不同? – Maritim
原谅我的术语,我对字典很好,这是我努力实现的结构。 – CaRDiaK
我刚刚读过你的问题,我明白你的意思:) – Maritim