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())
精彩评论