LINQ:在列表中的列表中使用where子句

时间:2017-03-25 04:33:15

标签: c# linq

我正在尝试在列表中的列表中使用where子句。

list = new List<Dictionary<string,object>>();
var dictionary = new Dictionary<string,object>();
var sub_list = new Dictionary<string,object>();
sub_list["id"] = 1;
sub_list["status"] = 310;

foreach(var itm in list)
{
  dictionary.Add(itm);
  dictionary.Add("sub_list", sub_list);
  list.Add(dictionary);
}

var showList = new List<Dictionary<string,object>>();
showList = list.Where(x => x["name] == "John")
               .Where(y => y.Where(kvp => kvp["status"] == 310)
               .ToList();

在列表中的keyvaluepair中使用where子句的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

好的,我想我知道你的问题是什么。您可以将LINQ查询和Lambda表达式完美地嵌套在一起,这样做非常安全。

但是,您将字典存储在另一个字典的对象中,因此当您使用kvp => kvp["status"] == 310时,您应该将kvp强制转换为Dictionary<string,object>并且投射字典对象是有风险的,并且这就是为什么你应该有强类型对象(即类)来存储这种数据结构。

简而言之,

showList = list.Where(x => x["name] == "John")
           .Where(y => y.Contains(kvp => ((Dictionary<string,object>)kvp.Value)["status"] == 310)
           .ToList();

纠正你的问题,但是让一个具有字典属性的类更多是OOP。

希望有所帮助:)

答案 1 :(得分:0)

由于listList of Dictionary of Dictionary,因此您需要使用折叠运算符(例如.All.Any)在1到多个关系中引入过滤器(谓词) ,.First等。

根据Emad的说法,使用非常弱的类型(例如object)并不是一个好习惯,因为您需要进行大量的投射,首先检查类型安全性。

我稍微加强了类型,虽然叶字典值仍然是弱类型的(因此在int比较中需要.Equals):

var nestedDictionary = new List<Dictionary<string, Dictionary<string, object>>>
{
    new Dictionary<string, Dictionary<string, object>>
    {
        {
            "Foo",
            new Dictionary<string, object>
            {
                {"Bar", "I'm a string"},
                {"status", 310}
            }
        },
        {
            "John",
            new Dictionary<string, object>
            {
                {"Bar", "I'm a string"},
                {"status", 310}
            }
        }
    },
    ... next top level dictionary here
};

var showList = nestedDictionary
    .Where(dic => dic.ContainsKey("John") 
        && dic["John"].Any(kvp => kvp.Key == "status" && kvp.Value.Equals(310)))
    .ToList();

修改

从评论中,您似乎想从图表中删除较低级别的对象(即不仅仅是对顶级元素进行过滤)。

您可以使用.Select(在您的情况下返回IEnumerable<IEnumerable<>>)或.SelectMany(这会使嵌套元素变平):

var allJohnsWithStatus310 = nestedDictionary
    .Where(dic => dic.ContainsKey("John"))
    .SelectMany(dic => dic["John"]
        .Where(kvp => kvp.Key == "status" && kvp.Value.Equals(310)))
    .ToList();