使用LINQ剪切列表

时间:2016-03-07 10:36:02

标签: c# linq

我有一个List,我希望在第一个真值之前剪切所有错误值,在最后一个真值之后剪切所有错误值。

我知道我可以通过每个方向的循环来做到这一点。我很好奇是否有更简单的方法来使用LINQ。

2 个答案:

答案 0 :(得分:2)

所以给出了这个输入:

var input = new List<bool>
{
    false,
    false,
    true, // first true
    true,
    false,
    true, // last true
    false
};

你想要true, true, false, true,对吧?

琐碎的方法是使用(Last)IndexOf

var firstTrue = input.IndexOf(true);
var lastTrue = input.LastIndexOf(true);

var indexed = input.Skip(firstTrue).Take(lastTrue - firstTrue + 1).ToList();

这将是最坏情况迭代列表两次,一次用于IndexOf调用,并且需要错误检查(如果输入中没有true怎么办?)。

如果你坚持使用LINQ,它会变得更难,因为功能性的prorgamming作为一个集合中的单个项目,而不是整个集合。因此,在评估每个列表项是否包含它们时,您需要在列表中继续向前扫描(以免第一个false停止搜索):

var output = input.SkipWhile(t => t == false)
                  .TakeWhile((b, i) => b == true || input.Skip(i + 2).Contains(true));

答案 1 :(得分:1)

说出您的输入如下:

var values= new List<bool>()
        { false, false,
          true, false, false ,true, false, true, //this is the part you want
          false, false, false};

最简单的方法当然是简单地获取true值的第一个和最后一个出现的索引,并获取这两个索引之间的内容。

if (values.Contains(true)) //check if there is actually at least one true.
{
    var firstIndex = values.IndexOf(true);
    var lastIndex = values.LastIndexOf(true);
    var count = lastIndex - firstIndex + 1; //include last index
    var result = values.GetRange(firstIndex, count);
}

如果你真的想使用LINQ,但不想担心前瞻,你可以使用SkipWhile()跳过第一个true的所有内容,然后反转列表,{{1}再次到第一个SkipWhile()

true