选择间隔linq

时间:2015-04-23 09:16:50

标签: c# linq

LINQ是否有某种方法可以选择具有快捷标准的某些数字。 像这样: 我有来自1 to 10000的号码。 我的标准是(4012..4190|4229),意思是在4012 to 4190和数字4229之间取数字:

 static int[] test(string criteria)
    {
        // criteria is 4012..4190|4229
        // select numbers from lab where criteria is met
        int[] lab = Enumerable.Range(0, 10000).ToArray();

        return lab;
    }

4 个答案:

答案 0 :(得分:3)

这对你的情况来说应该足够了:

return lab.Where((int1) => (int1 >= 4012 && int1 <= 4190) || int1 == 4229).ToArray();

另一种解析标准的快捷方法是使用RegEx:

Regex r = new Regex(@"\d+");
MatchCollection m = r.Matches(criteria);
int start = int.Parse(m[0].Value);
int end = int.Parse(m[1].Value);
int specific = int.Parse(m[2].Value);
return lab.Where((int1) => (int1 >= start && int1 <= end) || int1 == specific).ToArray();

答案 1 :(得分:3)

如果您的criteria始终是string,则需要某种方式将其解析为Func<int, bool,但它不是LINQ特定的。最后你需要这样的东西:

Func<int, bool> predicate = Parse(criteria);
return lab.Where(predicate).ToArray();

Parse的基本实现可能如下所示:

public static Func<int, bool> Parse(string criteria)
{
    var alternatives = criteria
        .Split('|')
        .Select<string, Func<int, bool>>(
            token =>
            {
                if (token.Contains(".."))
                {
                    var between = token.Split(new[] {".."}, StringSplitOptions.RemoveEmptyEntries);
                    int lo = int.Parse(between[0]);
                    int hi = int.Parse(between[1]);
                    return x => lo <= x && x <= hi;
                }
                else
                {
                    int exact = int.Parse(token);
                    return x => x == exact;
                }
            })
        .ToArray();

    return x => alternatives.Any(alt => alt(x));
}

答案 2 :(得分:1)

您可以连接两个序列

int[] lab = Enumerable.Range(4012, 4190-4012).Concat(Enumerable.Range(4229,1)).ToArray();

更新

您需要先解析传入的条件

static int[] test(string criteria)
    {
        // criteria is 4012..4190|4229
        // select numbers from lab where criteria is met

        // assume you parsed your criteria to 2 dimentional array
        // I used count for second part for convience
        int[][] criteriaArray = { new int[]{ 4012, 50 }, new int[]{ 4229, 1 } };

        var seq = Enumerable.Range(criteriaArray[0][0], criteriaArray[0][1]);

        for (int i = 1; i < criteriaArray.Length; i++)
        {
            int start = criteriaArray[i][0];
            int count = criteriaArray[i][1];
            seq = seq.Concat(Enumerable.Range(start, count));
        }


        return seq.ToArray();
    }

答案 3 :(得分:0)

你可以: Flatten[{Range[4012, 4190], 4229}]

在某种程度上,这也可以正常工作4012..4190|4229,但答案正是如此 - 从4012到4190和第4229项的项目清单。

Lambda只是模仿纯粹的功能。但是,除非你有免费的wolfram内核,否则使用这种方法可能不是最具成本效益的。但是,您不需要编写样板代码。