Упрощение булевой логики - PullRequest
0 голосов
/ 03 мая 2011

У меня есть функция, которая должна возвращать true, если все элементы проходят тест. Если происходит сбой только одного элемента, функция должна вернуть false. Если в коллекции нет элемента, функция должна вернуть false. Вот код:

    private bool TestAll()
    {
        bool finalResult = false;
        bool itemResult = false;

        foreach (var item in Items)
        {
            itemResult = Test(item);

            if (!finalResult && itemResult)
                finalResult = true;
            else if (finalResult && !itemResult)
                finalResult = false;
        }

        return finalResult;
    }

Как мне упростить логику в один if оператор, используя только одну bool переменную?

Ответы [ 6 ]

6 голосов
/ 03 мая 2011

Вы можете использовать метод расширения IEnumerable.All, чтобы протестировать все элементы, которые не выполняются при первом сбое метода Test.

private bool TestAll()
{
    return Items.All(Test);
}

Если вам все еще нужно проверить все элементы, вы можете использовать оператор присваивания AND:

if (!Items.Any()) return false;

bool result = true;

foreach (var item in Items)
{
  result &= Test(item);
}

return result;
2 голосов
/ 03 мая 2011

Если все тесты должны быть запущены , вы можете сделать это без LINQ:

private bool TestAll()
{
    var allTestsPassed = true;

    foreach (var item in Items)
    {
        allTestsPassed = Test(item) && allTestsPassed;
    }

    return allTestsPassed;
}

Вы можете сделать это с помощью LINQ:

private bool TestAll()
{
    return Items.Count(Test) == Items.Count();
}

Обновление: возврат false, если нет тестов для запуска

private bool TestAllWithoutLinq()
{
    if (Items.Count == 0) { // or something equivalent
        return false;
    }

    var allTestsPassed = true;

    foreach (var item in Items)
    {
        allTestsPassed = Test(item) && allTestsPassed;
    }

    return allTestsPassed;
}

private bool TestAllWithLinq()
{
    return Items.Any() && Items.Count(Test) == Items.Count();
}
1 голос
/ 03 мая 2011

Я понимаю, что на этот вопрос ответили, и самый короткий ответ - ответ LINQ.Подобно другим, но требует доли секунды мысли:

private bool TestAll()
{
    var passed = true;

    foreach (var item in Items)
    {
        if ( ! Test(item))
        {
            passed = false;
        }
    }

    return passed && Items.Count != 0;
}
0 голосов
/ 03 мая 2011

Это запустит все тесты, вернет false, если тестов нет, и вернет true, только если все тесты пройдут:

private bool TestAll() {
  if (Items.Count == 0) return false;
  bool passed = true;
  foreach(var item in Items) {
    if (!Test(item))
      passed = false;
  }
  return passed;
}
0 голосов
/ 03 мая 2011
private bool TestAll()
{
    foreach (var item in Items)
    {
        if(!(Test(item)) || Items.Count == 0)
        {
            return false;
        }
    }

return true;
}
0 голосов
/ 03 мая 2011

Кажется странным требованием, чтобы он возвращал false, если отказал только один элемент Я правильно читаю вопрос? Если это так, вы можете использовать следующее

private bool TestAll() {
  int failCount = 0;
  foreach (var item in Items) {
    if (!Test(item)) {
      failCount++;
    }
  }
  return failCount != 1;
}
...