让我们说这是我的清单{1,2,3,4,5,6,7,8,9}
现在我想将这些项目混合到以下列表中:{1,9,2,8,3,7,..}
基本上始终是左侧的一个项目和列表右侧的一个项目。
是否有可能只使用linq语句来创建它?
答案 0 :(得分:1)
是的,你可以使用LINQ(相当简短,甚至)来做到这一点,但它并不完全令人愉快:
所以:
var query = original.Zip(original.Reverse(), (x, y) => new[] { x, y })
.SelectMany(x => x)
.Take(original.Count());
如果我真的要使用此代码,我肯定会在那里发表评论...
答案 1 :(得分:0)
这是一个想法:
var sample = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var res = sample
.Select((z, i) => i % 2 == 0
? sample[i / 2]
: sample[sample.Count - i / 2 - 1])
.ToList();
基本上它使用模数来选择列表开头或结尾处的项目。
请注意我甚至没有使用枚举的z
值,所以虽然LINQ实际上是在这里使用的,但它不是简单的for
循环。
编辑:
如果你想要更快地计算的东西,可以试试没有LINQ的东西:
int count = sample.Count;
var res = new List<int>(count);
for (int i = 0; i < sample.Count; i++)
{
var iDividedByRwo = i / 2;
if (i % 2 == 0)
{
res.Add(sample[iDividedByRwo]);
}
else
{
res.Add(sample[count - iDividedByRwo - 1]);
}
}
编辑2:好的,我正在做你的工作但是......
private static void Main(string[] args)
{
var sample = Enumerable.Range(0, 100000).ToList();
var z1 = Stopwatch.StartNew();
for (int i = 0; i < 1000; i++)
{
Test1(sample);
}
z1.Stop();
Console.WriteLine(z1.ElapsedMilliseconds);
var z2 = Stopwatch.StartNew();
for (int i = 0; i < 1000; i++)
{
Test2(sample);
}
z2.Stop();
Console.WriteLine(z2.ElapsedMilliseconds);
Console.Read();
}
private static void Test1(IList<int> input)
{
var res2 = input
.Select((z, i) => i % 2 == 0
? input[i / 2]
: input[input.Count - i / 2 - 1])
.ToList();
}
private static void Test2(IList<int> input)
{
int count = input.Count;
var res = new List<int>(count);
for (int i = 0; i < input.Count; i++)
{
var iDividedByRwo = i / 2;
if (i % 2 == 0)
{
res.Add(input[iDividedByRwo]);
}
else
{
res.Add(input[count - iDividedByRwo - 1]);
}
}
}
结果:
4195
1136
如果您想获得最快的方法,请插入其他方法并比较结果。
答案 2 :(得分:0)
这是另一种方法:
var list = new List<int>{1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> alternatingOrder = list
.Select((i, index) => new
{
i,
Margin = index < list.Count / 2 ? index : list.Count - ++index
})
.OrderBy(x => x.Margin)
.Select(x => x.i)
.ToList();