比方说这是我的列表{1,2,3,4,5,6,7,8,9}将项目与Linq混合到一个新列表中
现在我想将这些项目混合到以下列表中:{1,9,2,8,3,7,..}
基本上总是一个项目从左侧和一个项目从右侧的列表。
是否有可能通过使用linq语句创建它?
比方说这是我的列表{1,2,3,4,5,6,7,8,9}将项目与Linq混合到一个新列表中
现在我想将这些项目混合到以下列表中:{1,9,2,8,3,7,..}
基本上总是一个项目从左侧和一个项目从右侧的列表。
是否有可能通过使用linq语句创建它?
这里有一个想法:
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
如果您想获得最快的方法,请插入其他方法并比较结果。
是的,你可以做到这一点只使用LINQ(相当简单,甚至是),但它并不完全令人愉快:
这样:
var query = original.Zip(original.Reverse(), (x, y) => new[] { x, y })
.SelectMany(x => x)
.Take(original.Count());
如果我真的要使用此代码,我肯定把评论在那里...
这里的另一种方法:
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();
自己的答案可能重复:http://stackoverflow.com/a/1758451/3629689;) – clarkitect 2014-10-20 11:53:05
@jeffdot:是的,'Interleave'你可以只使用'original.Interleave(original.Reverse())。拿(original.Count())' – 2014-10-20 11:53:46
谢谢Jon,你可以看看ken2k的答案,并告诉我哪个可能表现更好? – 2014-10-20 11:54:06