【问题标题】:How to sort a dictionary with three values in sequence如何按顺序对具有三个值的字典进行排序
【发布时间】:2018-09-16 05:39:55
【问题描述】:

所以我有一个数字和颜色值列表。

[1, Red]
[4, Yellow]
[5, Red]
[6, Yellow]
[8, White]
[9, Red]
[10, Yellow]
[13, White]
etc. etc.

字典整数最初是使用 Enumerable 在 1 - 100 之间的范围内随机生成的。 var lstNumbers = Enumerable .Range(1, 100).OrderBy(n => Guid.NewGuid().GetHashCode()) .ToList();

创建字典并用于将 ColorType 值分配给序列中的每个数字 Red、Yellow、White、Red、Yellow、White 等,等等。给列表中的所有数字。var map = new Dictionary<int, ColorType>();

然后我以几种不同的方式删除项目,这将我带到了排序中。我需要按值对这个字典中的最终列表进行排序,白色结果在顶部,黄色在中间,红色在底部。红

然后显示。

我想我可以使用一些 if 语句对颜色进行排序,或者为每种颜色设置参数,然后使用 Orderby 以按颜色值对结果进行排序。

我很难找出以这种方式对这些特定值进行排序的有效方法。

有什么想法吗?

【问题讨论】:

  • 你知道字典没有排序吗?
  • 您可以执行dict.OrderBy(c => c.Value == "White" ? 0 : c.Value == "Yellow" ? 1 : 2) 之类的操作。只是不要将结果放回字典,因为字典是无序结构。将它们放入List 或类似的地方。
  • @raichiks 我试着看看这是否有帮助,但我有 100 个关键整数,所以除非我想制作 100 个数据值,否则我认为重复的帖子不会有帮助。应该是更有效的方式吧?
  • @Evk 我尝试了 OrderBy 但我可能没有正确实现它,或者它可能不适用于我的场景,因为我得到了 == 运算符不能应用于“ColorType”操作数的错误和“字符串”。 foreach (var color in map.OrderBy(c => c.Value == "White" ? 0 : c.Value == "Yellow" ? 1 : 2)) { Console.WriteLine(color); }

标签: c# sorting dictionary key-value


【解决方案1】:

这里有一个提示:

Red = 100
Yellow = 110
White = 111

(只是说你想要的颜色顺序已经被你提到的颜色的 RGB 值隐含了。所以它应该是一个很好的顺序值来源。)

【讨论】:

    【解决方案2】:

    这是一个基于this answer的实现:

    public class CustomerComparer : IComparer<KeyValuePair<int, string>>
    {
        private List<string> orderedColors = new List<string>() { "White", "Yellow", "Red" };
    
        public int Compare(KeyValuePair<int, string> str1, KeyValuePair<int, string> str2)
        {
            return orderedColors.IndexOf(str1.Value) - orderedColors.IndexOf(str2.Value);
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var unsorted = new Dictionary<int, string>()
            {
                {1, "Red"},
                {4, "Yellow"},
                {5, "Red"},
                {6, "Yellow"},
                {8, "White"},
                {9, "Red"},
                {10, "Yellow"},
                {13, "White"}
            };
    
            var sorted = unsorted.OrderBy(x => x, new CustomerComparer());
    
            foreach (var entry in sorted)
            {
                Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
            }
            Console.ReadKey();
        }
    }
    

    你可以看看this article

    更新

    根据这个答案的 cmets,字典中的排序值似乎是一个来自 Enum 的数字。

    更新代码:

    public class CustomerComparer : IComparer<KeyValuePair<int, ColorType>>
    {
        private List<ColorType> orderedLetters = new List<ColorType>() { ColorType.White, ColorType.Yellow, ColorType.Red };
    
        public int Compare(KeyValuePair<int, ColorType> str1, KeyValuePair<int, ColorType> str2)
        {
            return orderedLetters.IndexOf(str1.Value) - orderedLetters.IndexOf(str2.Value);
        }
    }
    
    public enum ColorType
    {
        Red,
        Yellow,
        White
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var unsorted = new Dictionary<int, ColorType>()
            {
                {1, ColorType.Red},
                {4, ColorType.Yellow},
                {5, ColorType.Red},
                {6, ColorType.Yellow},
                {8, ColorType.White},
                {9, ColorType.Red},
                {10, ColorType.Yellow},
                {13, ColorType.White}
            };
    
            var sorted = unsorted.OrderBy(x => x, new CustomerComparer());
    
            foreach (var entry in sorted)
            {
                Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
            }
            Console.ReadKey();
        }
    }
    

    【讨论】:

    • 这看起来几乎可以让我到达那里,但我遇到了一个问题,因为我在字典中使用了用于颜色的自定义类型。我将每个 Enum 键整数颜色值分配为红色、白色、黄色、红色、白色、黄色等,并遍历所有 1 - 100 范围内的随机数字。public static ColorType Next(this ColorType color) { if (color == ColorType.Red) return ColorType.Yellow; if (color == ColorType.Yellow) return ColorType.White; return ColorType.Red; }
    • 因此,当我尝试在 compare 方法的 return 语句中将其转换为字符串时,会出现错误,因为它无法将其转换为字符串。
    • 请出示您的自定义类型代码,以便我为您提供帮助。
    • public enum ColorType { Red, Yellow, White } public static class ColorExtension { // Iterator for lstNumbers Enumerable public static ColorType Next(this ColorType color) { if (color == ColorType.Red) return ColorType.Yellow; if (color == ColorType.Yellow) return ColorType.White; return ColorType.Red; }
    • internal class Program { public static void Main(string[] args) { // Creating numbers ranging from 1 - 100 and randomizing var lstNumbers = Enumerable .Range(1, 100).OrderBy(n =&gt; Guid.NewGuid().GetHashCode()) .ToList(); // Start point for color assignment var startColor = ColorType.Red; var map = new Dictionary&lt;int, ColorType&gt;();
    【解决方案3】:

    您可以使用 Enum 对适合您需要的颜色进行排序。如果 identifier 只是一个字符串值,你必须按字符串值查找并将其转换为 int 值。如果以后有更多的颜色,或者顺序必须改变,只需修改 Enum。当然需要更新,如果在 Enum 中没有找到颜色,但是对于这个问题不是要添加的情况......

     public enum ColorCodes
    {
        White = 1,
        Yellow = 2,
        Red = 3
    }
    
    class Program
    {
        /// <summary>
        /// Sorts dictionary by color enum int sequence
        /// </summary>
        /// <param name="toOrder"></param>
        /// <returns></returns>
        public static Dictionary<int, string> DictionarySorter(Dictionary<int, string> toOrder)
        {
            return toOrder.OrderBy(x => (int)(ColorCodes)Enum.Parse(typeof(ColorCodes), x.Value)).ToDictionary(x => x.Key, x => x.Value);
        }
    
    
        static void Main(string[] args)
        {
    
            Dictionary<int, string> unsortedColors = new Dictionary<int, string>();
            unsortedColors.Add(1, "Red");
            unsortedColors.Add(4, "Yellow");
            unsortedColors.Add(5, "Red");
            unsortedColors.Add(6, "Yellow");
            unsortedColors.Add(8, "White");
            unsortedColors.Add(9, "Red");
            unsortedColors.Add(10, "Yellow");
            unsortedColors.Add(13, "White");
    
    
            var sortedDic = DictionarySorter(unsortedColors);
            foreach (var entry in sortedDic)
            {
                Console.WriteLine(string.Format("{0} - {1}", entry.Key, entry.Value));
            }
            Console.Read();
        }
    }
    

    正如其他人指出的那样 -dictionary 没有按顺序排序,因此可以使用代替 Dictionary sorter:

     public static List<KeyValuePair<int,string>> DictionarySorter(Dictionary<int, string> toOrder)
        {
            return toOrder.OrderBy(x => (int)(ColorCodes)Enum.Parse(typeof(ColorCodes), x.Value)).ToList();
        }
    

    【讨论】:

    • 这也可能有效。我为 Dictionary 提供的类型是 int、ColorType。这是一种自定义类型,我用它在程序前面以特定顺序将颜色分配给范围从 1 到 100 的随机数列表。public static ColorType Next(this ColorType color) { if (color == ColorType.Red) return ColorType.Yellow; if (color == ColorType.Yellow) return ColorType.White; return ColorType.Red; }
    • 这是我的字典:var map = new Dictionary&lt;int, ColorType&gt;();
    • 您可以将字典排序方法更改为public static List&lt;KeyValuePair&lt;int, ColorType&gt;&gt; DictionarySorter(Dictionary&lt;int, ColorType&gt; toOrder) { return toOrder.OrderBy(x =&gt; (int)(ColorCodes)Enum.Parse(typeof(ColorCodes), x.Value.ToString())).ToList(); }
    • 然后使用名为“map”的字典var sortMyDic = DictionarySorter(map); foreach (var number in sortMyDic) { Console.WriteLine(number); } Console.ReadLine();
    • 或者只使用您自己的枚举,如果默认情况下需要颜色顺序public static List&lt;KeyValuePair&lt;int, ColorType&gt;&gt; DictionarySorter(Dictionary&lt;int, ColorType&gt; toOrder) { return toOrder.OrderBy(x =&gt; (int)x.Value).ToList(); } 这是一个很好的解决方案并摆脱我的枚举,并且刚刚看到这个,如果您将代码发布在从头开始的问题
    猜你喜欢
    • 2015-04-06
    • 2021-12-20
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2014-01-26
    • 2020-09-26
    • 2019-08-10
    • 1970-01-01
    相关资源
    最近更新 更多