лямбда-выражение для проверки правильности списка - PullRequest
2 голосов
/ 16 апреля 2009

Я хочу написать лямбда-выражение, чтобы убедиться, что список упорядочен правильно. У меня есть список, в котором у человека есть свойство Name, например:

IList<Person> people = new List<Person>();
people.Add(new Person(){ Name = "Alan"});
people.Add(new Person(){ Name = "Bob"});
people.Add(new Person(){ Name = "Chris"});

Я пытаюсь проверить, что список упорядочен ASC по свойству Name. Итак, я что-то вроде

Assert.That(people.All(....), "list of person not ordered correctly");

Как я могу написать лямбду, чтобы проверить, что у каждого человека в списке есть имя меньше, чем у следующего человека в списке?

Ответы [ 4 ]

5 голосов
/ 16 апреля 2009

Вот альтернатива решению Джареда - оно почти такое же, но с использованием цикла foreach и логической переменной, чтобы проверить, является ли это первой итерацией. Я обычно нахожу это проще, чем повторять вручную:

public static bool IsOrdered<T>(this IEnumerable<T> source)
{
  var comparer = Comparer<T>.Default;
  T previous = default(T);
  bool first = true;

  foreach (T element in source)
  {
      if (!first && comparer.Compare(previous, element) > 0)
      {
          return false;
      }
      first = false;
      previous = element;
  }
  return true;
}
4 голосов
/ 16 апреля 2009

Я не верю, что есть какой-либо оператор LINQ, который в настоящее время занимается этим делом. Однако вы можете написать метод IsOrdered, который выполняет эту работу. Например.

public static bool IsOrdered<T>(this IEnumerable<T> enumerable) {
  var comparer = Comparer<T>.Default;
  using ( var e = enumerable.GetEnumerator() ) {
    if ( !e.MoveNext() ) {
      return true;
    }
    var previous = e.Current;
    while (e.MoveNext()) {
      if ( comparer.Compare(previous, e.Current) > 0) {
        return false;
      }
      previous = e.Current;
    }
    return true;
  }
}

Тогда вы можете использовать следующее для проверки вашего списка:

var isOrdered = people.Select(x => x.Name).IsOrdered();
0 голосов
/ 31 мая 2013

А как же:

people.SequenceEqual( people.OrderBy( x=>x.Name ) );

SequenceEqual () доступен с 3.5 Вы можете добавить Distinct () после OrderBy (), если хотите подтвердить, что дубликатов нет.

0 голосов
/ 13 октября 2011

Я знаю, что это старый вопрос, но у меня есть очень хорошее решение для этого с помощью Linq:

people.Zip(people.OrderBy(p => p.Name), (a, b) => a == b).All(eq => eq);

По сути, вы объединяете последовательность с упорядоченной последовательностью и проецируете значение bool, указывающее, равны ли обе записи:

"Alan"  -- "Alan"  => true
"Bob"   -- "Bob"   => true
"Chris" -- "Chris" => true

Затем с помощью метода All вы спрашиваете, являются ли все элементы в коллекции true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...