首页 > 解决方案 > C#按序列分区对数字进行排序

问题描述

我的数据如下:

5 2 2 1 3 3 4

我想在 C# 中输出如下:

1 2 3 4 5 2 3

所以基本上所有唯一值都按 ASC 顺序排序,而不是从剩余项目开始......

标签: c#

解决方案


我会说它很复杂……但它激起了我的兴趣……请注意,这个解决方案非常简单。如果您想要多字段排序或反向排序等,它会变得更加复杂:

public static class OrderByTest
{
    private static int Increment<TKey>(Dictionary<TKey, int> dict, TKey key)
    {
        int value;

        if (dict.TryGetValue(key, out value))
        {
            value++;
        }

        dict[key] = value;
        return value;
    }

    public static IEnumerable<TSource> OrderByPartition<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        var dict = new Dictionary<TKey, int>();

        var res = source.Select(x => new { Value = x, Partition = Increment(dict, keySelector(x)) }).OrderBy(x => x.Partition).ThenBy(x => keySelector(x.Value));

        foreach (var value in res)
        {
            yield return value.Value;
        }
    }
}

然后像这样使用它:

var values = new[] { 5, 2, 2, 1, 3, 3, 4 };
var ordered = values.OrderByPartition(x => x).ToArray();

它是一种 Linq 风格的解决方案,因此它会生成一个新的有序序列,而不是像Array.Sort. 基本思想是将分区号添加到您的集合中。为了获得分区号,我们使用一个包含已找到Dictionary<TKey, int>的相同元素数量的临时变量。TKey


推荐阅读