【问题标题】:sort a dictionary's keys based on its values; values represent arrays and sorting order varies - ascending/descending; c#根据字典的值对字典的键进行排序;值表示数组,排序顺序不同 - 升序/降序; C#
【发布时间】:2020-10-12 04:46:54
【问题描述】:

我想对对象列表进行排序。结构是Dictionary<object, double[]>,如下所示:

    Dictionary<int, double[]> dict = new Dictionary<int, double[]>{
    {object1, new double[]{0.02, 0.10, 0.30, 0.5}},
    {object4, new double[]{0.02, 0.10, 0.30, 0.2}},
    {object3, new double[]{0.02, 0.10, 0.30, 0.3}},
    {object2, new double[]{0.02, 0.10, 0.50, 0.4}}
    };

数组应该根据索引以不同的顺序排列。即第一个、第二个和第四个索引升序,第三个索引降序。所以最终,我应该得到:

object2, 0.02, 0.1, 0.5, 0.4
object4, 0.02, 0.1, 0.3, 0.2
object3, 0.02, 0.1, 0.3, 0.3
object1, 0.02, 0.1, 0.3, 0.5

我使用发布在here 的代码作为起点。我应该做什么样的调整?当然,我知道该方法将不再是通用的(数组长度无关)。我正在考虑创建一个与double[] 大小相同的bool[],其中True 代表升序排序,False 代表降序,但比较方法严格获取2 个参数。任何帮助将非常感激。谢谢!

【问题讨论】:

  • 您的代码如何知道哪些键应该按升序排序,哪些按降序排列?你试图让你的代码做到这一点?请重新填写tour,阅读what's on-topic hereHow to Ask,并提供minimal reproducible example。 “为我实现此功能”与此站点无关。你必须诚实地尝试,然后就你的算法或技术提出一个具体问题
  • @PranavHosangadi OP 写道,他不需要通用解决方案
  • @ЯрославВиталиевич 这跟什么有什么关系?
  • How's your code going to know which keys are supposed to be sorted ascending and which ones descending - 你写的。我假设 OP 只是想制作一个硬编码比较器
  • 亲爱的 Pranav,正如我所说,我创建了 bool[] = [True, True, False, True]。我的意图是将它用作比较方法的第三个参数。如你所知,那是行不通的。我恳请有关如何将这条附加信息集成到排序算法的提示/想法。感谢理解。

标签: c# sorting dictionary


【解决方案1】:

您可以使用 Linq 库。在字典上调用OrderBy

var x = dict.OrderBy(o => o.Value[0]).ThenBy(o => o.Value[1]).ThenBy(o => -o.Value[2]).ThenBy(o => o.Value[3]);

完整代码:

using System.Linq;
...........
public static void Main()
    {
        var object1 = 1;
        var object2 = 2;
        var object3 = 3;
        var object4 = 4;
        
        Dictionary<int, double[]> dict = new Dictionary<int, double[]>{
        {object1, new double[]{0.02, 0.10, 0.30, 0.5}},
        {object4, new double[]{0.02, 0.10, 0.30, 0.2}},
        {object3, new double[]{0.02, 0.10, 0.30, 0.3}},
        {object2, new double[]{0.02, 0.10, 0.50, 0.4}}
        };
        
        var x = dict.OrderBy(o => o.Value[0]).ThenBy(o => o.Value[1]).ThenBy(o => -o.Value[2]).ThenBy(o => o.Value[3]);
        
        // write ordered values
        foreach (var d in x)
        {
            Console.Write(d.Key + ", [");
            foreach (var v in d.Value)
                Console.Write(v + ", ");
            Console.WriteLine("]");
        }
    }

输出

2, [0.02, 0.1, 0.5, 0.4, ]
4, [0.02, 0.1, 0.3, 0.2, ]
3, [0.02, 0.1, 0.3, 0.3, ]
1, [0.02, 0.1, 0.3, 0.5, ]

【讨论】:

  • 感谢@Mike67。我知道这种 Linq 语法,但不知道我可以使用 -o.Value[2] 使其降序。感谢顶部的樱桃!
  • Linq 的ThenByDescending() 也是一个选项
  • 太棒了!甚至“更干净”!
【解决方案2】:

如果我没听错,请尝试使用此比较器:

    public class SequenceComparer : IComparer<IList<double>>
    {
        public SequenceComparer(bool[] markers)
        {
            Markers = markers;
        }

        public bool[] Markers { get; }
        
        public int Compare(IList<double> x, IList<double> y)
        {
            //check for null
            if (x == null || y == null || Markers == null)
            {
                throw new Exception("Null arrays are not valid");
            }

            //check identical count
            if (x.Count != y.Count || x.Count != Markers.Length)
            {
                throw new Exception("Invalid count");
            }

            for (var i = 0; i < x.Count; i++)
            {
                if (x[i].Equals(y[i]))
                {
                   continue;
                }

                var comparisonResult = x[i] > y[i] ? 1 : -1;
                
                //if marker is false, invert comparisonResult
                return Markers[i] ? comparisonResult : comparisonResult * -1;
            }

            //Your arrays are identical, just skip
            return 1;
        }
    }

您可以使用任意长度的数组并使用bool[] 标志来调整排序方向
使用示例:

var query = dict.OrderBy(pair => pair.Value, new SequenceComparer(new []{true, true, false, true}));

【讨论】:

  • 谢谢。这正是我的想法;非泛型,集成在 Compare 方法中。再次感谢。
  • 刚刚更新check identical count 条件。请使用最新版本
猜你喜欢
  • 2020-12-10
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多