我有以下数组:
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生成它
答案 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
。
要清楚,我认为您的原始代码更好......