Search code examples
c#linqmathsetfactorization

Linq Union/UnionAll/Concat


I'm trying to convert a simple piece of Math to Linq.

I want to bundle together the prime factors for several numbers into one collection. Consider the following integers.

8 = 2 * 2 * 2
12 = 2 * 2 * 3

The smallest number divisible by both 8 & 12 is 24, so I'd like the resultant group to contain

{ 2, 2, 2, 3 }

If I use Concat the result is {2,2,2,2,2,3} - not correct If I use Union the result is {2,3} - not correct

Is there a built in Linq Set Manipulation function which will recognise that it needs to keep the maximum number of occurences of an item (i.e. not add another if there are already enough there to satisfy if & add another if there aren't)


Solution

  • Well, it's not any existing function, as I don't think such exists, but pretty simple code is capable of handling this:

            var listA = new List<int> {2, 2, 2};
            var listB = new List<int> {2, 2, 3};
    
            var grouppedA = listA.GroupBy(i => i).Select(g => new { key = g.Key, count = g.Count()});
            var grouppedB = listB.GroupBy(i => i).Select(g => new { key = g.Key, count = g.Count()});
            var result = grouppedA
                .Union(grouppedB)
                .GroupBy(g => g.key)
                .SelectMany(g => Enumerable.Repeat(g.Key, g.Max(h => h.count)));
    
            foreach (int i in result)
            {
                Console.Write(i + " ");
            }
            Console.ReadKey();
    

    Output: 2 2 2 3