Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用LINQ删除最后一项_C#_Linq - Fatal编程技术网

C# 用LINQ删除最后一项

C# 用LINQ删除最后一项,c#,linq,C#,Linq,对于LINQ来说,这似乎是一项琐碎的任务(很可能是),但我不知道如何使用LINQ删除最后一项squence。当然,使用Take并传递序列-1的长度效果很好。然而,当在一行代码中链接多个LINQ时,这种方法似乎很不方便 IEnumerable<T> someList .... // this works fine var result = someList.Take(someList.Count() - 1); // but what if I'm chaining LINQ ?

对于LINQ来说,这似乎是一项琐碎的任务(很可能是),但我不知道如何使用LINQ删除最后一项squence。当然,使用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(...)........;
IEnumerable someList。。。。
//这个很好用
var result=someList.Take(someList.Count()-1);
//但如果我把LINQ锁起来呢?
var result=someList.Where(…).DropLast().Select(…)。。。。。。;
//我要把它拆开吗?
var temp=someList.Where(…);
var result=temp.Take(temp.Count()-1)。选择(…)。。。。。。。。;

在Python中,我只需执行seq[0:-1]。我试着传递-1以获取方法,但它似乎不能满足我的需要。

使用扩展方法,您可以很容易地做到这一点,或者使用您已经找到的表单,或者结合使用
Take
Count

someList.Reverse().Skip(1).Reverse()
public static IEnumerable<T> DropLast<T>(this IEnumerable<T> enumerable)
{
  return enumerable.Take(enumerable.Count()-1);
}
公共静态IEnumerable滴播(此IEnumerable可枚举)
{
返回enumerable.Take(enumerable.Count()-1);
}

对于.NET Core 2+和,您可以使用

对于其他平台,您可以编写自己的LINQ查询操作符(即on),例如:

static IEnumerable<T> SkipLast<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;
            }
        }
    }
}
静态IEnumerable SkipLast(此IEnumerable源代码)
{
使用(var e=source.GetEnumerator())
{
if(如MoveNext())
{
对于(var值=e.Current;e.MoveNext();值=e.Current)
{
收益回报值;
}
}
}
}

与其他方法不同,例如
xs.Take(xs.Count()-1)
,上面的方法只处理一次序列。

@LukeH,它是O(n),并且是OP想要的一行答案。哦,我为什么不考虑这个:)这是一种聪明而简单的方法,可以直接做现成的事情。不太确定性能意味着什么,但如果我只需要一种快速而肮脏的方法来完成,这是一种很好的方法。@Saeed:它是O(n),但它需要相当于通过序列的四次。Jamiec答案中的第一个例子也是一行和O(n),但只需要通过序列两次(或者如果序列实现了
ICollection
ICollection
),请注意,这也将整个序列存储在内存中-两次。如果序列非常长,那么可能会占用大量内存。是的,这种技术在时间上是O(n),但在空间上也是O(n),在空间中可能是O(1)。@Saeed:为什么IEnumerable必须取O(n)?例如,不管范围内有多少项,范围在空间中都是O(1)。难道第二种方法不能编译吗?Last()返回T,但不接受IEnumerable。我遗漏了什么吗?@Kei-可能是对的,我没有测试它,但是沿着这些思路的东西会起作用。编辑的回答除之外的
方法不适用于此,因为它还会从源序列中删除任何重复项。如果源代码是
{1,2,3,4,5,4,3,2,1}
,那么OP将期望结果是
{1,2,3,4,5,4,3,2}
;使用第二个示例(假设您修复了错误)将给出
{2,3,4,5}
。这同样有效:xs.TakeWhile((x,i)=>i