使用linq生成自定义数字序列

时间:2017-09-07 14:01:20

标签: c# .net linq

我有以下数组:

var sequence = new double?[] {null, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
                             18, 19, 20, 22, 24, 26, 28, 30,32, 34, 36, 38, 40, 44,48, 52, 
                             56, 60, 64, 68,72, 76, 80, 88, 96, 104, 112, 120, 128, 136, 144
                              };

我想获得相同的序列,但是使用linq生成它

4 个答案:

答案 0 :(得分:3)

这是另一个版本:

public static IEnumerable<int> Numbers()
{
    int[] inc = {1, 2, 4, 4, 8, 8, 8, 8};

    for (int n = 3; n <= 144; n += inc[n / 20])
        yield return n;
}

或者如果你想有点迟钝:

public static IEnumerable<int> Numbers()
{
    for (int n = 3; n <= 144; n += "12448888"[n/20]-'0')
        yield return n;
}

(第二个建议是开玩笑 - 不要这样做,这是不可读的!)

[编辑]这是第三种方法,略显理智:

public static IEnumerable<int> Numbers()
{
    for (int n = 3; n <= 144; n += 1 + (n>=20?1:0) + (n>=40?2:0) + (n>=80?4:0))
        yield return n;
}

答案 1 :(得分:2)

我有两个可能的版本用于生成数组的数字部分:

每个范围的Concat版本

var r = Enumerable.Range(3, 17)
    .Concat(Enumerable.Range(0, 10).Select(i => 20 + i * 2))
    .Concat(Enumerable.Range(0, 10).Select(i => 40 + i * 4))
    .Concat(Enumerable.Range(0, 9).Select(i => 80 + i * 8))
    .ToArray();

使用SelectMany和值元组的版本:

var r2 = new[] { (3, 17), (0, 10), (0, 10), (0, 9) }
    .SelectMany((_, i) => Enumerable.Range(_.Item1, _.Item2).Select(n => 20 * (1 << (i - 1)) + n * (1 << i)))
    .ToArray();

天气版本的版本比原版更具可读性:)

答案 2 :(得分:2)

  

20增加后2 ..经过40增量后4 ...经过80增量后增加8 ...直到144

在这种情况下不要使用linq,除非您故意要增加理解代码的难度。一个简单的循环:

static IEnumerable<double?> Data()
{
    yield return null;
    for (int value = 3; value <= 144; value++) // increment by 1 by default
    {
        yield return value;
        if (value >= 20) value += 1;
        if (value >= 40) value += 2;
        if (value >= 80) value += 4;
    }
}

答案 3 :(得分:1)

这值得我考虑:

var result = Enumerable.Range(3, 17)
    .Concat(Enumerable.Range(10, 10).Select(z => z * 2))
    .Concat(Enumerable.Range(10, 11).Select(z => z * 4))
    .Concat(Enumerable.Range(11, 8).Select(z => z * 8));
var resultWithNull = new double?[] {null}.Concat(result.Select(z => (double?)z)).ToArray();

第二个var是在开始时连接null

要清楚,我认为您的原始代码更好......