Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumerable.Repeat with Union and Take does not return 'Take' values

Very simple problem. I have a list of values which I want to pad out with empty values such that I always have X number of items returned.

List<int> list = new List<int>() { 10, 20, 30 };

IEnumerable<int> values = list
     .OrderByDescending( i => i )
     .Union( Enumerable.Repeat( 0 , 5 ) );

foreach (var item in values.Take(5))
   Console.Write( item + " ");

I would expect an output like "30 20 10 0 0 " But surprisingly I only get "30 20 10 0".

foreach (var i in Enumerable.Repeat( 0, 5 ).Take(3))
    Console.Write( i + " " );

This code will return "0 0 0 ". Likewise "list.Take(3)" returns "30 20 10 ".

like image 486
Ian Quigley Avatar asked Mar 07 '26 17:03

Ian Quigley


2 Answers

The reason is that Enumerable.Union removes duplicates. So you may want to use Enumerable.Concat instead which dsoesn't remove duplicates.

Another option i would prefer is to use Enumerable.ElementAtOrdefault to select the elements from an index created by Enumerable.Range where the second argument is the desired count:

IEnumerable<int> values = Enumerable.Range(0, 5)
            .Select(i => list.ElementAtOrDefault(i))
            .OrderByDescending(i => i);
like image 141
Tim Schmelter Avatar answered Mar 09 '26 07:03

Tim Schmelter


The notion of union, as a set-theory operation, has an implicit "distinct". If you don't want that: use Concat instead of Union.

like image 43
Marc Gravell Avatar answered Mar 09 '26 05:03

Marc Gravell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!