All*_*lix 4 c# linq dictionary
我有两个类型的字典Dictionary<string, List<List<string>>。我想从字典1中选择与字典2中的值/条目匹配的条目范围。
例如,字典1具有键01, 01.1,字典2具有与01, 01.1.键匹配的值1
首先,我从字典2的键1处获得条目,如下所示:
var dictList = (from entry in DbDict
where entry.Key == id.ToString() // id = 1
select entry).ToList();
Run Code Online (Sandbox Code Playgroud)
我试图通过linq选择这些,如下所示:
var matchingEntries = (from entry in ExcelDict
where ExcelDict.Keys.Equals(dictList[0].Value)
select entry).ToList();
Run Code Online (Sandbox Code Playgroud)
并尝试了更多方法,但不会返回任何结果。
如何从字典1的键对与字典2的值匹配的值对中获取范围?
编辑1:
Dictionary 1:
Key Value
01 "these", "are"
..., ...
01.1 "just", "some"
..., ...
02 "sample", "values"
..., ...
Dictionary 2:
Key Value
1 "01", "01.1"
"foo", "bar"
..., ...
2 "02", "02.21"
"value1" "value2"
Run Code Online (Sandbox Code Playgroud)
编辑2:
预期产量:
"01", "01.1"
"foo", "bar"
Run Code Online (Sandbox Code Playgroud)
编辑3:
注释中要求的可编译输入。这正是我要处理的结构:
var dict1 = new Dictionary<string, List<List<string>>>();
dict1.Add("01", new List<List<string>> { new List<string> { "these" }, new List<string> { "are" } });
dict1.Add("01.1", new List<List<string>> { new List<string> { "just" }, new List<string> { "some" } });
dict1.Add("02", new List<List<string>> { new List<string> { "sample" }, new List<string> { "values" } });
var dict2 = new Dictionary<string, List<List<string>>>();
dict2.Add("1", new List<List<string>> { new List<string> { "01", "01.1" }, new List<string> { "foo", "bar" } });
dict2.Add("2", new List<List<string>> { new List<string> { "02", "value1" }, new List<string> { "02.21", "value2" } });
Run Code Online (Sandbox Code Playgroud)
编辑4:
回复晚了非常抱歉。高朗·戴夫(Gaurang Dave)在评论中的建议和被接受的答案都对我有用。感谢大家的帮助!
你写了:
我想从字典1中选择与字典2中的值/条目匹配的条目范围。
从Edit2的输出中,您似乎想从Dictionary 2中获取值。您不会对Keys进行任何操作。每个值都是一个List<List<string>>。在您的示例中,键1的值的第一列表中的所有字符串在字典1中都有对应的键。显然,这是确定完整值在输出中的条件。
键2的值的第一个列表具有一个元素,该元素不是字典1中的键。因此,输出中没有任何值。
不清楚:如果第二个列表匹配而不是第一个列表匹配怎么办?
Key Value
3 "foo", "bar"
"01", "01.1"
Run Code Online (Sandbox Code Playgroud)
这也应该是您的最终结果吗?
不清楚您想要结果a List<List<string>>还是List<string>所有匹配值都大?重复值呢?
假设您只想检查列表列表中的第一个列表:
我们将仅查看字典2中的值,这些键将被丢弃。然后从该值集合的每个列表中选取第一个(如果有),并将单独的属性记住完整列表。
当然,空列表不应该出现在最终结果中,因此,我们只保留那些具有第一个元素的列表:
// Only use the values of dictionary 2:
IEnumerable<List<List<string>>> dict2Values = dictionary2.Values
// then for easy comparison extract the first list
var separatedFirstList = dict2Values.Select(listOfLists=> new
{
FirstList = listOfLists.FirstOrDefault(), // this is a List<string> or null
AllLists = listOfLists, // original List<List<string>> where FirstList is the first
})
// keep only the elements that have a first list:
.Where(stringListWithFirstElement => stringListWithFirstElement.FirstList != null);
Run Code Online (Sandbox Code Playgroud)
到目前为止,我们已经将您的示例词典转换为:
{
FirstString = {"01", "01.1"},
FullList = {"01", "01.1"}, {"foo", "bar"}, {...}, {...},
},
{
FirstString = {"02", "02.21"},
FullList = {"02", "02.21"}, {"value1" "value2"}, ...
},
{
FirstString = ...,
FullList = ...,
},
...
Run Code Online (Sandbox Code Playgroud)
从这个序列中,我们只想将WHERE ALL元素保留在FirstStringare的key中Dictionary 1:
IEnumerable<string> keysDictionary1 = dictionary1.Keys;
var matchingItems = separatedFirstList
.Where(item => item.FirstList.All(txt => keysDictionary1.Contains(txt));
Run Code Online (Sandbox Code Playgroud)
您会看到“哪里”和“全部”。
结果:
{
FirstString = {"01", "01.1"},
FullList = {"01", "01.1"}, {"foo", "bar"}, {...}, {...},
},
...
Run Code Online (Sandbox Code Playgroud)
带有的FirstString = {"02", "02.21"}被删除,因为并非firstString的所有元素都在字典1中,
最后:摆脱FirstString:
List<List<String>> finalResult = matchingItems
.Select(matchingItem => matchingItem.FullList);
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望结果为一List<String>:
List<string> finalResult = matchingItems.SelectMany(matchingItem => matchingItem.FullList);
Run Code Online (Sandbox Code Playgroud)
TODO:考虑创建一个大的LINQ语句。由于中间步骤使用延迟执行,因此我不确定这是否会提高性能。但是我确信它将降低可读性。