简体   繁体   中英

How to Make a default value for IGrouping<TKey, TSource> with count = 0?

I like C# linq and also the extension methods style.

Here is a simple code to get how many times of each number is there in an array :

    static void Main(string[] args)
    {
        int[] nums = { 1, 2, 2, 3, 3, 3 };
        var groups = nums.GroupBy(n => n);
        //var keynums = nums.Distinct();//ok
        var keynums = Enumerable.Range(0, 10);//causes ArgumentNullException
        var timesDict = keynums.ToDictionary(n => n,
            n =>
            groups.FirstOrDefault(g => g.Key == n)
            //((groups.FirstOrDefault(g => g.Key == n))??what can be put here)
            .Count());
        foreach (var kv in timesDict)
        {
            Console.WriteLine($"{kv.Key}\t{string.Join(" ", kv.Value)}");
        }
        Console.ReadKey();
    }

The code works, but if I want know the nums are always [0-9] , and want to get how many times [0-9] appears (if not appears, the count should be 0 ).

So the code will get ArgumentNullException , which makes sense because FirstOrDefault gets null .

So to fix this, I want to use the ?? operator, and give it a default value. but I cannot think of how to construct such value.

How would you solve it? please do not use other styles such as if , select new {} .

How about using C#6 null-propagation like this?

groups.FirstOrDefault(g => g.Key == n)?.Count() ?? 0

if FirstOrDefault returns null, ?.Count() will not be evaluated anymore and not throw an exception.

You can use like this:

var higherLimits = new[] { 10, 20, 30 };
var ranges = items.GroupBy(item => higherLimits.First(higherLimits => higherLimits >= item));

This will avoid null issue altogether.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM