使用Linq选择列表中的一系列成员

时间:2010-03-08 18:53:15

标签: c# linq

给出一个像这样的元素列表:

int[] ia = new int[] { -4, 10, 11, 12, 13, -1, 9, 8, 7, 6, 5, 4, -2, 
                        6, 15, 32, -5, 6, 19, 22 };

Linq是否有一种简单的方法可以按照“从-1到下一个负数(或列表耗尽)中选择元素”的方式进行操作? -1的成功结果是(-1,9,8,7,6,5,4)。使用-2将给出结果(-2,6,15,32)。

不是作业问题。我只是看一个使用boolfor循环和if的实现,想知道是否有更简洁的方法。

4 个答案:

答案 0 :(得分:11)

查看TakeWhile Linq扩展方法。只要条件为真,就从列表中取出项目,跳过其余项目。

示例:

int[] ia = new int[] { -4, 10, 11, 12, 13, -1, 9, 8, 7, 6, 5, 4, -2, 
                        6, 15, 32, -5, 6, 19, 22 };

var result = ia
             .SkipWhile(i => i != -1)
             .Skip(1)
             .TakeWhile(i => i >= 0);

注意SkipWhile之后的Skip(1)。 SkipWhile会跳过所有内容,但不包括匹配元素。 TakeWhile然后采取项目,但不包括匹配元素。因为-1不大于或等于零,所以得到一个空结果。

答案 1 :(得分:5)

更新

这次我测试了代码......使用TakeWhile的两个参数形式,即使不满足(j == 0)的测试,我们也可以强制它接受第一个元素i。 / p>

ia.SkipWhile(i => i != -1).TakeWhile((i, j) => i >= 0 || j == 0)

TakeWhile(Func<int, int, bool>)需要一个带有两个参数的函数/ lambda。第一个是要测试的值,第二个是元素的索引。

答案 2 :(得分:0)

它必须是Linq吗?您可以使用Extensions方法获得更清晰的解决方案。

int[] ia = new int[] { -4, 10, 11, 12, 13, -1, 9, 8, 7, 6, 5, 4, -2, 
                        6, 15, 32, -5, 6, 19, 22 };

// Call the Extension method
int[] results = ia.SelectRangeLoop(-2);

// Print Results
for (int i = 0; i < results.Length; i++)
{
    Console.Write(" {0} ", results[i]);
}

SelectRangeLoop的方法如下。

public static int[] SelectRangeLoop(this int[] value, int startNumber)
{
    List<int> results = new List<int>();

    bool inNegative = false;

    for (int i = 0; i < value.Length; i++)
    {
        if (value[i] == startNumber)
        {
            inNegative = true;

            results.Add(value[i]);

            continue;
        }

        if (inNegative && value[i] < 0)
        {
            break;
        }

        if (inNegative)
        {
            results.Add(value[i]);
        }
    }

    return results.ToArray();
}

答案 3 :(得分:0)

var first = ia.Select((i, index) => new {i, index}).Where((i, index) => i.i == x).First();
var ind = first.index;
var second = ia.SkipWhile( (i, index) => index <= ind).TakeWhile(i => i > 0);
var ints = new[]{first.i}.Union(second);