Подтвердить что ты не робот

Удалить последний элемент с помощью LINQ

Возможный дубликат:
Как взять все, кроме последнего элемента в последовательности, используя LINQ?

Похоже на тривиальную задачу с LINQ (и, вероятно, это так), но я не могу понять, как удалить последний элемент squance с LINQ. Использование Take и прохождение длины последовательности - 1 отлично работает. Тем не менее, этот подход кажется весьма неудобным при объединении нескольких LINQ в одной строке кода.

IEnumerable<T> someList ....

// this works fine
var result = someList.Take(someList.Count() - 1);


// but what if I'm chaining LINQ ?
var result = someList.Where(...).DropLast().Select(...)......;

// Will I have to break this up?
var temp = someList.Where(...);
var result = temp.Take(temp.Count() - 1).Select(...)........;

В Python я мог бы сделать seq [0: -1]. Я попытался передать -1 методу Take, но, похоже, он не делает то, что мне нужно.

4b9b3361

Ответ 1

Вы можете написать свой собственный оператор запроса LINQ (то есть метод расширения на IEnumerable<T>), например:

static IEnumerable<T> WithoutLast<T>(this IEnumerable<T> source)
{
    using (var e = source.GetEnumerator())
    {
        if (e.MoveNext())
        {
            for (var value = e.Current; e.MoveNext(); value = e.Current)
            {
                yield return value;
            }
        }
    }
}

В отличие от других подходов, таких как xs.Take(xs.Count() - 1), вышеупомянутое будет обрабатывать последовательность только один раз.

Ответ 2

someList.Reverse().Skip(1).Reverse()

Ответ 3

Вы можете легко сделать это с помощью метода расширения, используя либо форму, которую вы уже нашли, либо комбинацию Take и Count

public static IEnumerable<T> DropLast<T>(this IEnumerable<T> enumerable)
{
  return enumerable.Take(enumerable.Count()-1);
}