比较字典的键和另一个字典的值

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)在评论中的建议和被接受的答案都对我有用。感谢大家的帮助!

Har*_*lse 5

你写了:

我想从字典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语句。由于中间步骤使用延迟执行,因此我不确定这是否会提高性能。但是我确信它将降低可读性。