假设我有一个清单{1,3,5,7,9,11}
我想使用像
这样的代码浏览列表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
}
所以如上所述对它们进行了排序我需要获得交替元素,所以理想情况下这样可以应用于此。
答案 0 :(得分: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
答案 1 :(得分:3)
这应该可以解决问题:
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);
答案 2 :(得分:1)
订购遵循一个模式,取决于项目,您的排序逻辑不存在匹配的第一个和最后一个,匹配第二个和前一个之后,依此类推。 =&GT; 1,n,2,n-1,... 所以基本上你必须遍历list =&gt;
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();
}
答案 3 :(得分:1)
针对任何项目(不仅仅是int
)的可重复使用的tic-tac方法可以是:
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
是什么,例如,如果source
是T[]
,或IList<T>
或其他什么,则提供更好的实施。
答案 4 :(得分:0)
的另一个选项是不使用OrderBy,而是使用自定义枚举器。 (为了举例,我省略了边界检查和其他东西)
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)您不创建数据副本 在内存中(在大数组的情况下可能有害)
您只需以某种特定方式滚动您已有的数据。