从.Net中的字典对象中获取唯一的配对

时间:2011-09-16 01:18:54

标签: .net linq

假设我有一个字符串对象String,List(of String)看起来像。

BU1
--All, BU
CON1
--ALL, EMP, CONF, CON1
SS1
--ALL, EMP, SS

如何获取包含不同匹配列表的对象,如此...

ALL, ALL, ALL --> Distinct is ALL
ALL, EMP, ALL --> Distinct is ALL, EMP
ALL, EMP, EMP --> Distinct is ALL, EMP --> exists don't add
BU, ALL, ALL --> Distinct is BU, ALL
BU, EMP, ALL --> Distinct is BU, EMP, ALL
BU, EMP, EMP --> Distinct is BU, EMP

这应该非常简单,我使用LINQ Intersect和Except以及递归函数,但我还没有找到一个成功的组合。

此列表只是一个小例子。实际列表的宽度和宽度都要大得多。

提前致谢。

1 个答案:

答案 0 :(得分:4)

我认为您正在寻找执行每个列表的cartesian product并获取不同的元组(每个元组仅包含不同的值)。

这种算法并不是非常有效;它会生成一些等于所有列表长度乘积的集合,并比较这些集合以获得最终的不同结果。您需要进行一些小的修改以使其不区分大小写,但您没有说这是否是必需的。

Dictionary<string, List<string>> Data = new Dictionary<string, List<string>>()
{
    {"BU1", new List<string>(){"ALL", "BU"}},
    {"CON1", new List<string>(){"ALL", "EMP", "CONF", "CON1"}},
    {"SS1", new List<string>(){"ALL", "EMP", "SS"}},
};

IEnumerable<IEnumerable<string>> Empty = Enumerable.Repeat(Enumerable.Empty<string>(), 1);
Data.Aggregate(Empty, 
    (accumulator, kvp) => 
        from a in accumulator 
        from i in kvp.Value 
        select a.Concat(Enumerable.Repeat(i, 1)))
    .Select(set => new HashSet<string>(set))
    .Distinct(HashSet<string>.CreateSetComparer());

这会产生以下输出集:

HashSet<String> (1 item)
ALL
HashSet<String> (2 items)
ALL
EMP
HashSet<String> (2 items)
ALL
SS
HashSet<String> (3 items)
ALL
EMP
SS
HashSet<String> (2 items)
ALL
CONF
HashSet<String> (3 items)
ALL
CONF
EMP
HashSet<String> (3 items)
ALL
CONF
SS
HashSet<String> (2 items)
ALL
CON1
HashSet<String> (3 items)
ALL
CON1
EMP
HashSet<String> (3 items)
ALL
CON1
SS
HashSet<String> (2 items)
BU
ALL
HashSet<String> (3 items)
BU
ALL
EMP
HashSet<String> (3 items)
BU
ALL
SS
HashSet<String> (2 items)
BU
EMP
HashSet<String> (3 items)
BU
EMP
SS
HashSet<String> (3 items)
BU
CONF
ALL
HashSet<String> (3 items)
BU
CONF
EMP
HashSet<String> (3 items)
BU
CONF
SS
HashSet<String> (3 items)
BU
CON1
ALL
HashSet<String> (3 items)
BU
CON1
EMP
HashSet<String> (3 items)
BU
CON1
SS

更新:这是VB.NET中的相同算法(它看起来非常相似):

Dim Empty As IEnumerable(Of IEnumerable(Of String)) = Enumerable.Repeat(Enumerable.Empty(Of String)(), 1)
Data.Aggregate(Empty, _
    Function(accumulator, kvp) _
        From a in accumulator _
        From i in kvp.Value _
        Select a.Concat(Enumerable.Repeat(i, 1))) _
    .Select(Function([set]) New HashSet(Of String)([set])) _
    .Distinct(HashSet(Of String).CreateSetComparer())