Performing a union type of two IEnumerable collections

Say you have two collections of integers:

IEnumerable<int> col1=new List<int> {2,3,3,5,7,11,11,11,13}; IEnumerable<int> col2=new List<int> {5,7,7,7,11,19}; 

Now I would like to create a third collection of col3 , such that for every single element that appears in either col2 or col2 , col3 will contain this element with at least as many events as the maximum number of entries in col1 or col2, but no more. Let me show you the final result, and then clarify:

  IEnumerable<int> col3=...; 

The contents of col3 should be:

{2,3,3,5,7,7,7,11,11,11,13,19}

Another way to describe the contents of col3 as a result of this β€œpseudo-union” operation is that it must contain enough elements of each value, but no more so that either of the two source collections can be formed individually (i.e., one by one, from the entire range of numbers in col3) by extracting elements from col3 .

If there is still confusion about what I mean when I say "one at a time," imagine that col1 and col2 are collections of different types of marbles with duplicates. I want to create col3 so that I have a minimum number of different types of marbles so that I can remove enough marbles from col3 to form col1 , then return the marble to col3 and then remove enough marble to form col2 .

I would really like it if the answer used LINQ to come up with one expression that solves the problem, because the two methods that I have been thinking about so far include:

  • Combining dictionaries containing histograms (i.e. the number of occurrences of each integer).
  • Building a dictionary from col1 , and then performing a mark and paste operation on col2 , resulting in a dictionary with enough counts for each integer to satisfy my criteria.

Update. The collections of input data are guaranteed to be sorted (i.e., monotonous and not reduced), and the resulting set should be in the same order.

+4
source share
1 answer

Like this:

 var groups1 = col1.ToLookup(e => e); var groups2 = col2.ToLookup(e => e); var col3 = col1.Union(col2) .SelectMany(e => Enumerable.Repeat(e, Math.Max( groups1[e].Count(), groups2[e].Count() ) )); 
+6
source

All Articles