C#:对键为 List<object> 的字典进行排序

Posted

技术标签:

【中文标题】C#:对键为 List<object> 的字典进行排序【英文标题】:C#: Sorting a dictionary in which the keys are 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、日期、名称等)都被“链接”,无论我需要使用什么数据类型。 【参考方案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;
        

【讨论】:

以上是关于C#:对键为 List<object> 的字典进行排序的主要内容,如果未能解决你的问题,请参考以下文章

C# list<object>和json互转

如何在 C# 中将 List<object> 转换为 Hashtable?

c# list<object>的数据怎么导出到excel

C# 在运行时将 Enumerable.Iterator 强制转换为已知 List<Object>

C#中 list<object> 去除重复的数据 求最简单的方法!!

c# 两个list的交集问题!