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 

是我试图实现的可能性,还是我需要找到不同的方法?

+2

字典与键值对的集合有什么不同? – Maritim

+0

原谅我的术语,我对字典很好,这是我努力实现的结构。 – CaRDiaK

+0

我刚刚读过你的问题,我明白你的意思:) – Maritim

我想你只想迭代“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标志一起一个关键和一个价值;丢弃不完整的组
  • 最后,将组转换为键值对的字典。