开发者

Get unique pairings from dictionary object in .Net

Suppose I have a dictionary object of String, List (of String) that looks like.

BU1
--All, BU
CON1
--ALL, EMP, CONF, CON1
SS1
--ALL, EMP, SS开发者_C百科

How can I get an object that contains a lists of distinct matches like so...

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

etc

This should be really simple and I've played with LINQ Intersect and Except and recursive functions but I haven't hit on a winning combination.

This list is just a mini example. The real list would be much bigger in both breadth and width.

Thanks in advance.


I think you're looking to perform the cartesian product of each of your lists and get the distinct tuples (each tuple containing only distinct values).

This algorithm isn't terribly efficient; it's going to generate a number of sets equal to the product of the lengths of all your lists and compare these sets to get the final distinct result. You would need to make some minor modifications to make it case-insensitive, but you didn't say if that was required.

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());

This produces the following output sets:

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

Update: Here is the same algorithm in VB.NET (it looks very much the same):

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())
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜