我似乎无法弄清楚如何订购一组大,小,大的小数据。
假设我有:
32.00
95.00
60.00
14.00
62.00
分组最终会结束:
95 and 62
60 and 32
14 all by himself
我可以将它粘贴在数据表中,但即使这样......也不完全确定如何获得所需的结果。
答案 0 :(得分:1)
另一种方法是使用Enumerator
并编写自定义LINQ扩展方法
此方法更有效,因为它消除了多次枚举:
public static class LinqExtensions
{
public static IEnumerable<Tuple<T, T>> GroupBy2<T>(this IEnumerable<T> source)
{
var enumerator = source.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
T first = enumerator.Current;
if (!enumerator.MoveNext()) {
yield return new Tuple<T, T>(first, default(T));
yield break;
}
T second = enumerator.Current;
yield return new Tuple<T, T>(first, second);
}
}
finally
{
if (enumerator != null)
enumerator.Dispose();
}
}
}
用法示例:
var data = new List<double>() { 32.00, 95.00, 60.00, 14.00, 62.00 };
// As Tuple<double, double>[] array:
var results = data.OrderByDescending(x => x).GroupBy2().ToArray();
// Iterate through IEnumerable<Tuple<double, double>>:
foreach (var pair in data.OrderByDescending(x => x).GroupBy2())
{
Console.WriteLine($"{pair.Item1} {pair.Item2}");
}
结果:
32 95
60 14
62 0
对于非偶数项,您可以提供另一种行为,而不是default(T)
例如,如果对不存在,则此实现将null
作为第二个元组项返回,但它不适用于类。
public static IEnumerable<Tuple<T, T?>> GroupBy2<T>(this IEnumerable<T> source)
where T : struct
{
var enumerator = source.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
T first = enumerator.Current;
if (!enumerator.MoveNext()) {
yield return new Tuple<T, T?>(first, null);
yield break;
}
T second = enumerator.Current;
yield return new Tuple<T, T?>(first, second);
}
}
finally
{
if (enumerator != null)
enumerator.Dispose();
}
}
答案 1 :(得分:0)
下面的代码按顺序排列条目,然后将奇数条目(第一个,第三个等)与偶数条目(第二个,第四个等)与Zip结合起来。
using System;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
public class Program
{
static void Main(string[] args)
{
var data = new List<double>() {32.00, 95.00, 60.00, 14.00, 62.00};
var ordered = data.OrderByDescending(z => z);
var oddGrouped = ordered.Select((value, index) =>
new {value, index}).Where(z => z.index % 2 == 0).Select(z => z.value);
var evenGrouped = ordered.Select((value, index) =>
new { value, index }).Where(z => z.index % 2 == 1).Select(z => (int?)z.value)
.Concat(new List<int?>() { null} ); // extra entry at the end in case there are an odd number of elements
var result = oddGrouped.Zip(evenGrouped, (odd, even) => new Tuple<double, double?>(odd, even)).ToList();
foreach (var entry in result)
{
Console.WriteLine(entry);
}
Console.ReadLine();
}
}
}