C# Формат foreach l oop как лямбда - PullRequest
4 голосов
/ 04 февраля 2020

Я начинаю с C# и получил следующий класс:

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;
    }
}

Теперь я хотел бы сократить следующую часть кода с помощью лямбда-выражений:

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

Я пробовал с:

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

И все же я сталкиваюсь с этой ошибкой: CS0201

Я прихожу с Java и не могу выяснить, почему это не работает. Может кто-нибудь объяснить, что я должен делать по-другому (и почему)?

Ответы [ 5 ]

6 голосов
/ 04 февраля 2020

Это будет работать только тогда, когда после фильтрации есть хотя бы один элемент.

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

Если их не может быть (метод не может суммироваться), вы можете использовать это

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

По соображениям производительности вам, вероятно, следует избегать использования индексатора и самостоятельно перебирать словарь.

var defaultZero = new KeyValuePair<string, int>(string.Empty, 0);
var sum = this
          .Where(pair => pair.Key.StartsWith(prefix))
          .DefaultIfEmpty(defaultZero)
          .Sum(pair => pair.Value);
4 голосов
/ 04 февраля 2020

Вы можете достичь этого, используя System.Linq, используя Where метод для фильтрации ключей, а затем Sum значения для отфильтрованных ключей, используя Func<string, int> селектор

public int sum(String prefix)
{
    return base.Keys.Where(key => key.StartsWith(prefix)).Sum(key => base[key]);
}
3 голосов
/ 04 февраля 2020

Вы можете поставить его как простой Linq запрос:

using System.Linq;

...

int sum = this
  .Where(pair => pair.Key.StartsWith(prefix))
  .Sum(pair => pair.Value);
0 голосов
/ 04 февраля 2020

Для производительности избегайте индексатора (ie: звонки на base[key]), если можете. Здесь вы можете напрямую работать с перечислением KeyValuePair:

public int Sum(string prefix) => this.Where(kvp => kvp.Key.StartsWith(prefix)).Sum(kvp => kvp.Value);
0 голосов
/ 04 февраля 2020

Вы можете использовать Linq:

            var sum = base.Keys.Where(key => key.StartsWith(prefix))
                          .Sum(key => base[key]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...