我正在尝试在列表中的列表中使用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子句的正确方法是什么?
答案 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)
由于list
是List 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();