使用Linq将项目混合到新列表中

时间:2014-10-20 11:45:20

标签: c# linq

让我们说这是我的清单{1,2,3,4,5,6,7,8,9}

现在我想将这些项目混合到以下列表中:{1,9,2,8,3,7,..}

基本上始终是左侧的一个项目和列表右侧的一个项目。

是否有可能只使用linq语句来创建它?

3 个答案:

答案 0 :(得分:1)

是的,你可以使用LINQ(相当简短,甚至)来做到这一点,但它并不完全令人愉快:

  • 反向列表
  • 用原始列表压缩它以获得对(1,9),(2,8)等
  • 展平结果
  • 仅采用原始数字

所以:

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();