Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Format foreach loop as Lambda

Tags:

c#

lambda

linq

I am getting started with C# and got the following class:

using System;
using System.Collections.Generic;

class PrefixMapSum : Dictionary<String, int> {

    public bool insert(String key, int value) {
        return base.TryAdd(key, value);
    } 

    public int sum(String prefix) {
        int sum = 0;

        foreach (String key in base.Keys) {
            if (key.StartsWith(prefix)) {
                sum = sum + base[key];
            }
        }

        return sum;
    }
}

Now I'd love to shorten the following part of the code with lambda-expressions:

        foreach (String key in base.Keys) {
            if (key.StartsWith(prefix)) {
                sum = sum + base[key];
            }
        }

I tried with:

new List<String>(base.Keys).ForEach(key => key.StartsWith(prefix) ? sum = sum + base[key] : sum = sum);

Yet i am running into this error: CS0201

I am coming from Java and I can't quite figure out why it does not work. Can anyone explain what I should do differently (and why)?

like image 937
Rüdiger Avatar asked Dec 10 '22 01:12

Rüdiger


1 Answers

This will only work when there is at least one element after the filtering.

base.Keys
   .Where(key=> key.StartsWith(prefix))
   .Sum(base[key])

If there can be none(The method cannot sum), you can use this DefaultIfEmptyso you will have the sum as 0.

base.Keys
   .Where(key=> key.StartsWith(prefix))
   .Select(key=> base[key])
   .DefaultIfEmpty(0)
   .Sum()

For performance reasons you would probably like to avoid using the indexer, and iterate the dictionary yourself.

var defaultZero = new KeyValuePair<string, int>(string.Empty, 0);
var sum = this
          .Where(pair => pair.Key.StartsWith(prefix))
          .DefaultIfEmpty(defaultZero)
          .Sum(pair => pair.Value);

If you need to handle the case where there is no element separately you can do something like

var elements =this
   .Where(pair => pair.Key.StartsWith(prefix))
   .Select(x=>x.Value);
if(!elements.Any()){
    // your logic here
}else{
    sum= elements.Sum();
    // other stuff
}
like image 127
kkica Avatar answered Dec 27 '22 00:12

kkica