比方說這是我的列表{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