2014-03-27 91 views
0

列表的开始和结束之间交替可以说我有一个列表{1,3,5,7,9,11}排序依据使用LINQ

我想用代码列表以去像

foreach (int myInt in myIntList.OrderBy(...)) 
{ 
    /// Do stuff 
} 

但是,这里的顺序是1然后11然后3然后9然后5然后7.我怎么会这样做顺序等?

我的实际情况稍微复杂一些在for循环看起来像这样:

foreach (Tuple<string, int, int, int> im in iconMappings.OrderBy(i => i.Item4).ThenByDescending(i => i.Item3)) 
{ 
    // Do stuff 
} 

所以已经下令他们像上面然后我需要获得交流元素,所以会非常喜欢的答案,可以是适用于此。

+3

_“但这里的顺序是1然后11然后3然后9然后5然后7”_这是否意味着这是你想要的结果? –

+0

是的,有效地用通用术语来说,n个项目的期望顺序是第1个然后第n个然后是第2个然后是第(n-1)个第3个等等 – Knightsy

+2

@Knightsy不需要'OrderBy',只需执行'for'循环并操纵每次索引。虽然这假定已经有序的集合。 –

回答

5

这给你想要的顺序:

List<int> myIntList = new List<int>(new[] { 1, 3, 5, 7, 9, 11 }); 

var result = myIntList 
    .Select((v, i) => new { Value = v, Index = i }) 
    .OrderBy(v => Math.Min(v.Index, Math.Abs((myIntList .Count - 1) - v.Index))) 
    .Select(v => v.Value); 

foreach (var v in result) 
{ 
    Console.WriteLine(v.ToString()); 
} 

给出:

1 
11 
3 
9 
5 
7 
+0

其中x是从x.Count中来的? – Knightsy

+0

@Knightsy错字,抱歉 - 修正。 – BartoszKP

1

排序遵循一个模式,根据项目,您的排序逻辑存在不匹配的第一个和最后一个,匹配第二个和上一个之前等等。 => 1,N 2,N-1,... 所以基本上你会在列表中有环路=>

var myNewList = new List<...>(); 
foreach(int i = 0, i < myItems.Count, i++) 
{ 
myNewList.add(myItems.First()); 
myNewList.add(myItems.Last()); 
myItems.Remove(myItems.First()); 
myItems.Remove(myItems.Last(); 
} 
+2

您还需要检查每次迭代中是否剩余1个以上的元素,因为您的第一个和最后一个元素是相同的,并且Remove()方法会爆炸。 – Tarec

+1

确实,以上是伪代码,未经测试,并不能保证成功,但它确实为您提供了如何解决问题的想法。 – woutervs

3

这应该做的TRIC K:

IEnumerable<int> alternatingOrder = intList 
    .Select((i, index) => new 
    { 
     i, 
     Margin = index < intList.Count/2 ? index : intList.Count - ++index 
    }) 
    .OrderBy(x => x.Margin) 
    .Select(x => x.i); 
0

另一种选择通过不使用排序依据,但自定义枚举。 (我省略边界检查和其他的东西了一个例子)

public IEnumerable<int> GetNext(List<int> data) 
{  
     int leftIndex = 0; 
     int rightIndex = data.Count() -1; 
     while(leftIndex < rightIndex) 
     { 
     yield return data[leftIndex++];   
     yield return data[rightIndex--];  

     } 
} 

使用本该像

foreach(var a in GetNext(list)){...} 

好处是,

1)你不改变oringinal阵列
2)您不会在内存中创建数据副本 (这可能对大数组有影响)

您只需以某种特定方式滚动您已有的数据。

1

一组的任何物品可重复使用的井字法(不只是int)可能是:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var numbers = new[] {1, 3, 5, 7, 9, 11, 13}; 

     foreach (var num in numbers.TicTac()) 
     { 
      Console.WriteLine(num); 
     } 

     Console.Read(); 
    } 
} 

static class Extensions 
{ 
    public static IEnumerable<T> TicTac<T>(this IEnumerable<T> source) 
    { 
     var count = source.Count(); 

     var leftIterator = source.GetEnumerator(); 
     var rightIterator = source.Reverse().GetEnumerator(); 

     int returned = 0; 
     bool right = false; 

     while (returned < count) 
     { 
      if (right) 
      { 
       rightIterator.MoveNext(); 
       yield return rightIterator.Current; 
      } 
      else 
      { 
       leftIterator.MoveNext(); 
       yield return leftIterator.Current; 
      } 

      returned++; 
      right = !right; 
     } 
    } 
} 

在你的情况,你要么承担阵列已经订购,或在订购在打电话之前。

然后你就可以对其进行优化来了解什么是source,比如提供更好的实施方案,如果sourceT[]IList<T>或什么的。