LINQ 在 C# 中查询具有多个键值选择的嵌套字典
LINQ querying nested dictionary with multiple key value selection in C#
我遇到了一个问题,找不到合适的解决方案。我有一个嵌套字典,其布局如下:
var dict = new Dictionary<int, Dictionary<string , dynamic>>()
{
0 : {Name : "abc" , marks1 : 05 , Marks2 : 10 , marks3 : 39},
1 : {Name : "efg" , marks1 : 20 , Marks2 : 30 , marks3 : 25},
2 : {Name : "hig" , marks1 : 30 , Marks2 : 40 , marks3 : 33},
3 : {Name : "xyz" , marks1 : 40 , Marks2 : 10 , marks3 : 50}
}
我正在尝试使用 LINQ 进行查询以获取这些查询的 id
,这些查询是 true
,但我无法 select 两个或三个查询条件。对于一个键值,下面的查询工作正常:
var query = from id in dict
from info in id.Value
where (info.Key == "marks1" && Convert.ToDouble(info.Value) > 10)
select id
但是当我尝试 2 或 3 个条件来获取行的 id 时,例如在它下面 不起作用。
var query = from id in dict
from info in id.Value
where (info.Key == "marks1" && Convert.ToDouble(info.Value) > 10)
&& (info.Key == "marks2" && Convert.ToDouble(info.Value) > 20)
select id
此外,如果我必须将这些值相互比较,例如 marks1
的值应该大于 mark2
和 mark3
。我怎样才能执行这样的查询?特别是当我不允许像这样按键访问值时:
info["marks1"] > ( info["mark2"] && info["marks3"] )
在 LINQ 中,因为它给我以下错误:
cannot apply indexing with [] to an expression of type 'keyvaluepair <
string , dynamic>
我试过了,效果很好
var result = dict.Where(x => x.Value.Any(y => y.Key == "marks1" && int.Parse(y.Value) > 10))
.Where(x => x.Value.Any(y => y.Key == "marks2" && int.Parse(y.Value) > 31));
你可以使用
var result= dict.Where(x=>Convert.ToDouble(x.Value["marks1"])>10
&& Convert.ToDouble(x.Value["Marks2"])>20)
.Select(x=>x.Key);
输出
1
2
外部来源:
dict
是一个KeyValuePairs
的序列,其中Key是一个int
,Value是里面的Dictionary<string, dynamic>
。因此,id
是此 KeyValuePair 序列中的一个元素:它是这样一个 KeyValuePair。
内部来自:
id.Value
是一个 Dictionary<string, dynamic>
,它是一串键值对,其中每个键都是一个字符串,每个值都是动态的。
您不需要内部字典中的所有 KeyValuePairs,您只需要其中的一些:
where (info.Key == "marks1" && Convert.ToDouble(info.Value) > 10)
&& (info.Key == "marks2" && Convert.ToDouble(info.Value) > 20)
如果我读到这里,您只需要内部字典中的那些 KeyValuePairs,其字符串 Key 等于 "marks1" 以及等于 "marks2"。你确定你想要那个吗?在我看来,结果将是一个空集合。
唉,你没写需求,我只好猜了。
我认为,从外部字典的每个 KeyValuePair 元素中,您都需要 Key(即外部字典中的 int),以及内部字典中具有
- 要么 (Key == "marks1" AND Convert.ToDouble(info.Value) > 10)
- 或(键 == "marks2" 和 Convert.ToDouble(info.Value)> 20)
我不太熟悉查询语法,所以我将改用 methodSyntax。
Dictionary<int, Dictionary<string, dynamic>> dict = ...;
var result = dict.Select( outerKeyValuePair => new
{
Key = outerKeyValuePair.Key,
Values = outerKeyValuePair.Value
// I don't want all values from the inner dictionary
// I only want those where (Key == "marks1" and ...) OR (Key == "marks2 and ...)
.Where(innerKeyValuePair =>
(innerKeyValuePair.Key == "marks1" && Convert.ToDouble(innerKeyValuePair.Value) > 10)
||
(innerKeyValuePair.Key == "marks2" && Convert.ToDouble(innerKeyValuePair.Value) > 20))
// from the remaining inner KeyValuePairs select the properties that you want
.Select(innerKeyValuePair => new
{
Name = innerKeyValuePair.Key,
Value = innerKeyValuePair.Value,
})
.ToList(),
});
换句话说:您的外部字典是一系列外部键值对。从这个序列中的每个 keyValuePair,创建一个新对象,包含两个属性:Key
和 Values
.
Key
属性 是您的键值对中的键。
Values
属性是一个列表。它包含由内部字典创建的对象,这些对象属于外部字典中 Key 的值。
这个内部字典也是一个键值对序列。我只保留其中一些内部 KeyValuePairs,即只保留那些:
- 键等于 "marks1" AND Convert.ToDouble(值)大于 10
- OR: Key 等于 "marks2 AND Convert.ToDouble(value) 大于 20
从内部字典的每个剩余 KeyValuePair 中,我创建了一个包含属性 Name
和 Value
.
的新对象
Name
是内部 KeyValuePair 的键(等于 "marks1" 或 "marks2")
Value
是这个内部 KeyValuePair 的值。
当然如果你想要其他属性,你可以Select他们而不是我选择的那些:
.Select(innerKeyValuePair => new
{
Marks = innerKeyValuePair.Key, // equals "marks1" OR "marks2"
Value = Convert.ToDouble(innerKeyValuePair.Value),
})
.ToList(),
你可以像这样展开字典:
dict.Select(item=> new {
Id = item.Key,
Name = item.Value["Name"],
marks1 = Convert.ToDouble(item.Value["marks1"]),
marks2 = Convert.ToDouble(item.Value["marks2"]),
marks3 = Convert.ToDouble(item.Value["marks3"])
}
)
.Where(item=> item.marks1 > 10 &&
item.marks2 > 20)
.Select(item=> item.Id)
此查询returns记录的id。如果您需要所选数据的完整记录,您可以使用:
dict.Select(item=> new {
item = item,
Name = item.Value["Name"],
marks1 = Convert.ToDouble(item.Value["marks1"]),
marks2 = Convert.ToDouble(item.Value["marks2"]),
marks3 = Convert.ToDouble(item.Value["marks3"])
}
)
.Where(item=> item.marks1 > 10 &&
item.marks2 > 20)
.Select(item=> item)
我遇到了一个问题,找不到合适的解决方案。我有一个嵌套字典,其布局如下:
var dict = new Dictionary<int, Dictionary<string , dynamic>>()
{
0 : {Name : "abc" , marks1 : 05 , Marks2 : 10 , marks3 : 39},
1 : {Name : "efg" , marks1 : 20 , Marks2 : 30 , marks3 : 25},
2 : {Name : "hig" , marks1 : 30 , Marks2 : 40 , marks3 : 33},
3 : {Name : "xyz" , marks1 : 40 , Marks2 : 10 , marks3 : 50}
}
我正在尝试使用 LINQ 进行查询以获取这些查询的 id
,这些查询是 true
,但我无法 select 两个或三个查询条件。对于一个键值,下面的查询工作正常:
var query = from id in dict
from info in id.Value
where (info.Key == "marks1" && Convert.ToDouble(info.Value) > 10)
select id
但是当我尝试 2 或 3 个条件来获取行的 id 时,例如在它下面 不起作用。
var query = from id in dict
from info in id.Value
where (info.Key == "marks1" && Convert.ToDouble(info.Value) > 10)
&& (info.Key == "marks2" && Convert.ToDouble(info.Value) > 20)
select id
此外,如果我必须将这些值相互比较,例如 marks1
的值应该大于 mark2
和 mark3
。我怎样才能执行这样的查询?特别是当我不允许像这样按键访问值时:
info["marks1"] > ( info["mark2"] && info["marks3"] )
在 LINQ 中,因为它给我以下错误:
cannot apply indexing with [] to an expression of type 'keyvaluepair < string , dynamic>
我试过了,效果很好
var result = dict.Where(x => x.Value.Any(y => y.Key == "marks1" && int.Parse(y.Value) > 10))
.Where(x => x.Value.Any(y => y.Key == "marks2" && int.Parse(y.Value) > 31));
你可以使用
var result= dict.Where(x=>Convert.ToDouble(x.Value["marks1"])>10
&& Convert.ToDouble(x.Value["Marks2"])>20)
.Select(x=>x.Key);
输出
1
2
外部来源:
dict
是一个KeyValuePairs
的序列,其中Key是一个int
,Value是里面的Dictionary<string, dynamic>
。因此,id
是此 KeyValuePair 序列中的一个元素:它是这样一个 KeyValuePair。
内部来自:
id.Value
是一个 Dictionary<string, dynamic>
,它是一串键值对,其中每个键都是一个字符串,每个值都是动态的。
您不需要内部字典中的所有 KeyValuePairs,您只需要其中的一些:
where (info.Key == "marks1" && Convert.ToDouble(info.Value) > 10)
&& (info.Key == "marks2" && Convert.ToDouble(info.Value) > 20)
如果我读到这里,您只需要内部字典中的那些 KeyValuePairs,其字符串 Key 等于 "marks1" 以及等于 "marks2"。你确定你想要那个吗?在我看来,结果将是一个空集合。
唉,你没写需求,我只好猜了。
我认为,从外部字典的每个 KeyValuePair 元素中,您都需要 Key(即外部字典中的 int),以及内部字典中具有
- 要么 (Key == "marks1" AND Convert.ToDouble(info.Value) > 10)
- 或(键 == "marks2" 和 Convert.ToDouble(info.Value)> 20)
我不太熟悉查询语法,所以我将改用 methodSyntax。
Dictionary<int, Dictionary<string, dynamic>> dict = ...;
var result = dict.Select( outerKeyValuePair => new
{
Key = outerKeyValuePair.Key,
Values = outerKeyValuePair.Value
// I don't want all values from the inner dictionary
// I only want those where (Key == "marks1" and ...) OR (Key == "marks2 and ...)
.Where(innerKeyValuePair =>
(innerKeyValuePair.Key == "marks1" && Convert.ToDouble(innerKeyValuePair.Value) > 10)
||
(innerKeyValuePair.Key == "marks2" && Convert.ToDouble(innerKeyValuePair.Value) > 20))
// from the remaining inner KeyValuePairs select the properties that you want
.Select(innerKeyValuePair => new
{
Name = innerKeyValuePair.Key,
Value = innerKeyValuePair.Value,
})
.ToList(),
});
换句话说:您的外部字典是一系列外部键值对。从这个序列中的每个 keyValuePair,创建一个新对象,包含两个属性:Key
和 Values
.
Key
属性 是您的键值对中的键。
Values
属性是一个列表。它包含由内部字典创建的对象,这些对象属于外部字典中 Key 的值。
这个内部字典也是一个键值对序列。我只保留其中一些内部 KeyValuePairs,即只保留那些:
- 键等于 "marks1" AND Convert.ToDouble(值)大于 10
- OR: Key 等于 "marks2 AND Convert.ToDouble(value) 大于 20
从内部字典的每个剩余 KeyValuePair 中,我创建了一个包含属性 Name
和 Value
.
Name
是内部 KeyValuePair 的键(等于 "marks1" 或 "marks2")
Value
是这个内部 KeyValuePair 的值。
当然如果你想要其他属性,你可以Select他们而不是我选择的那些:
.Select(innerKeyValuePair => new
{
Marks = innerKeyValuePair.Key, // equals "marks1" OR "marks2"
Value = Convert.ToDouble(innerKeyValuePair.Value),
})
.ToList(),
你可以像这样展开字典:
dict.Select(item=> new {
Id = item.Key,
Name = item.Value["Name"],
marks1 = Convert.ToDouble(item.Value["marks1"]),
marks2 = Convert.ToDouble(item.Value["marks2"]),
marks3 = Convert.ToDouble(item.Value["marks3"])
}
)
.Where(item=> item.marks1 > 10 &&
item.marks2 > 20)
.Select(item=> item.Id)
此查询returns记录的id。如果您需要所选数据的完整记录,您可以使用:
dict.Select(item=> new {
item = item,
Name = item.Value["Name"],
marks1 = Convert.ToDouble(item.Value["marks1"]),
marks2 = Convert.ToDouble(item.Value["marks2"]),
marks3 = Convert.ToDouble(item.Value["marks3"])
}
)
.Where(item=> item.marks1 > 10 &&
item.marks2 > 20)
.Select(item=> item)