【问题标题】:Ordering Data in a grouped way Big Small, Big Small以分组方式排序数据 Big Small,Big Small
【发布时间】:2017-06-29 16:14:43
【问题描述】:

我似乎无法弄清楚如何订购一组大大小小的数据。

假设我有:

32.00
95.00
60.00
14.00
62.00

分组将结束:

95 and 62
60 and 32
14 all by himself

我可以将其粘贴在数据表中,但即便如此……我也不完全确定如何获得所需的结果。

【问题讨论】:

  • 你的代码在哪里?
  • 听起来像是“1+1 销售”的解决方案 :)
  • 不了解您的订单。 Big small/big small 将变为 (95,14),(62,32),60。

标签: c#


【解决方案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)
例如,如果 pair 不存在,此实现将 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();
    }
}

【讨论】:

    【解决方案2】:

    以下代码将条目按顺序排列,然后将奇数条目(第一、第三等)与偶数条目(第二、第四等)与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();
            }
        }
    }
    

    【讨论】:

    • 您能帮我了解oddGrouped.Zip 在做什么吗?请......刚刚测试了你的代码,它工作得很好!谢谢!
    • 啊!明白了……现在说得通了。超级好用!不知道这存在。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多