【问题标题】:C#: Sorting a dictionary in which the keys are List<object>C#:对键为 List<object> 的字典进行排序
【发布时间】:2021-02-12 20:19:49
【问题描述】:

大家好! Tl;博士我有一个Dictionary&lt;string, List&lt;object&gt;&gt; 叫 具有以下键的“表”:

"id" being int,
"date" being Datetime,
"name", "entry1", "entry2", "entry3" being strings.

以及List&lt;object&gt; 列表中键的所有值。我想通过name 字段订购字典,名称类似于“John Doe”。我尝试使用 .OrderBy() ,它要么抛出异常,要么只订购那个键而不是整个字典。例如:var result = table.Orderby(pairs =&gt; pairs.Value[2]); 会抛出异常,因为对象不是字符串。 如何才能做到这一点?谢谢!

编辑: 该表用于使用 Excel 文件中的值:

           foreach (var key in table.Keys)
            {
                for (int i = 0; i < max; i++)
                {
                    switch (key)
                    {
                        case "id":
                            worksheet.Cells[i + 1, j].Value = ConversionWrapper<int>((int)table[key][i]);
                            break;
                        case "date":
                            worksheet.Cells[i + 1, j].Value = ConversionWrapper<string>((DateTime)table[key][i]);
                            break;
                        case "name":
                        case "entry1":
                        case "entry2":
                        case "entry3":
                        case "entry4":
                            worksheet.Cells[i + 1, j].Value = ConversionWrapper<string>((string)table[key][i]);
                            break;
                        default:
                            break;
                    }
                }

                ++j;
            }

       private static T ConversionWrapper<T>(object elem)
        {
            switch (elem)
            {
                case int:
                case string:
                    return (T)elem;
                case DateTime:
                    return (T)(object)((DateTime)elem).ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
                default:
                    throw new ArgumentException();
            }
        }

Method to extract the values:

        private static Dictionary<string, List<object>> GetAllElementsLM(SqlConnection conn)
        {
            string query;
            string[] columns = { "id", "date", "name", "entry1", "entry2", "entry3", "entry4" };
            var dic = new Dictionary<string, List<object>>();

            conn.Open();

            foreach (var elem in columns)
            {
                dic.Add(elem, new List<object>());

                query = $@"SELECT {elem} FROM ""feedback""";

                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            dic[elem].Add(reader.GetValue(0));
                        }
                    }
                }
            }

            conn.Close();

            return dic;
        }

【问题讨论】:

  • "我有一个名为 "table" 的 Dictionary&lt;string, List&lt;object&gt;&gt; 带有以下键" 考虑到 intDateTime 不是从 string 派生的,这是不可能的。
  • @JohnathanBarclay 键是字符串,我指的是我将对象值转换为
  • 您不需要对字典进行排序。如果你这样做了,那么 Dictionary 不是要使用的正确数据结构。字典专为键/值查找而设计
  • 您想要一本有序的字典吗?或者您是否尝试将字典投影到 new 有序数据结构中?
  • @mjwills 我不“想要”字典。这些值是从 SQL 表中提取的,我发现字典似乎很合适。我希望所有 7 个条目(id、日期、名称等)都被“链接”,无论我需要使用什么数据类型。

标签: c# list linq sorting dictionary


【解决方案1】:

您要排序的类(本例中为列表)需要实现 IComparer 接口。然后 OrderBy 运算符调用 IComparer.Compare 来确定排序顺序。

IComparer.Compare

所以你需要创建一个扩展 List 并实现 IComparer 的类。在此类的比较方法中,您可以执行任何必要的操作来确定哪个列表更大(例如,基于列表中的某个值)。然后,您的字典会将这个新类作为第二种类型。

【讨论】:

    【解决方案2】:

    最终使用了我的结构的List

    条目结构:

    readonly struct Entries
        {
            public int Id { get; }
            public DateTime Date { get; }
            public string Name { get; }
            public string Entry1 { get; }
            public string Entry2 { get; }
            public string Entry3 { get; }
            public string Entry4 { get; }
    
            public Entries(int id, DateTime date, string name, string entry1, string entry2, string entry3, string entry4) =>
                    (Id, Date, Name, Entry1, Entry2, Entry3, Entry4) = (id, date, name, entry1, entry2, entry3, entry4);
        }
    

    获取元素个数的方法:

            private static int GetMaxNumber(SqlConnection conn)
            {
                int i = 0;
                string query;
    
                conn.Open();
    
                query = $@"SELECT id FROM ""feedback""";
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            ++i;
                        }
                    }
                }
    
                conn.Close();
    
                return i;
            }
    

    获取元素:

            private static IEnumerable<Entries> GetAllElementsClass(SqlConnection conn)
            {
                string query;
                List<int> id;
                List<DateTime> date;
                List<string> name, entry1, entry2, entry3, entry4;
                int max = GetMaxNumber(conn);
    
                conn.Open();
    
                query = $@"SELECT id FROM ""feedback""";
    
                id = new List<int>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            id.Add((int)reader.GetValue(0));
                        }
                    }
                }
    
                query = $@"SELECT date FROM ""feedback""";
    
                date = new List<DateTime>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            date.Add((DateTime)reader.GetValue(0));
                        }
                    }
                }
    
                query = $@"SELECT name FROM ""feedback""";
    
                name = new List<string>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            name.Add((string)reader.GetValue(0));
                        }
                    }
                }
    
                query = $@"SELECT entry1 FROM ""feedback""";
    
                entry1 = new List<string>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            entry1.Add((string)reader.GetValue(0));
                        }
                    }
                }
    
                query = $@"SELECT entry2 FROM ""feedback""";
    
                entry2 = new List<string>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            entry2.Add((string)reader.GetValue(0));
                        }
                    }
                }
    
                query = $@"SELECT entry3 FROM ""feedback""";
    
                entry3 = new List<string>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            entry3.Add((string)reader.GetValue(0));
                        }
                    }
                }
    
                query = $@"SELECT entry4 FROM ""feedback""";
    
                entry4 = new List<string>();
    
                using (var command = new SqlCommand(query, conn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            entry4.Add((string)reader.GetValue(0));
                        }
                    }
                }
    
                for (int i = 0; i < max; i++)
                {
                    yield return new Entries(id[i], date[i], name[i], entry1[i], entry2[i], entry3[i], entry4[i]);
                }
    
                conn.Close();
            }
    

    对它们进行排序:

            private static List<Entries> SortEntries(SqlConnection conn)
            {
                var entries = new List<Entries>();
    
                foreach (var element in GetAllElementsClass(conn))
                {
                    entries.Add(element);
                }
    
                entries = entries.OrderBy(x => x.Name).ToList();
    
                return entries;
            }
    

    【讨论】:

      猜你喜欢
      • 2015-01-14
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 2011-12-11
      相关资源
      最近更新 更多