簡體   English   中英

使用C#對嵌套詞典進行排序

[英]Sorting a nested dictionaries using C#

我有一個字典對象,其類型如下。

Dictionary<string, Dictionary<Roles, Dictionary<Period, List<Product>>>>

具有“准備者”和“批准者”作為項目的角色(是一個枚舉)。 同樣,Period是另一個具有“ Ahead”和“ Past”項目的枚舉。

該列表包含各種產品的列表。

我在字典中具有以下分層結構中的項目。

"Sachin" --> Roles.Preparer --> Period.Past --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products
"Sachin" --> Roles.Approver --> Period.Past --> Products

我將不得不按以下順序對字典進行排序。

"Sachin" --> Roles.Preparer --> Period.Ahead --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products
"Sachin" --> Roles.Preparer --> Period.Past --> Products
"Sachin" --> Roles.Approver --> Period.Past --> Products

此結構是必需的,因為我將必須遍歷每個項目,並且應將其添加為郵件的一部分。

實際的代碼是這樣的。

`using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Basics
{
    class Product
    {
        public string Name { get; set; }
        public int Days { get; set; }

    }

    enum Period
    {
        Ahead,
        Past
    }

    enum Roles
    {
        Preparer,
        Approver
    }

    class Program
    {
        static void Main(string[] args)
        {
            DictionaryProcessing(new string[] { "sriram123@yahoo.com", "abhishek321@yahoo.com" });
        }

        private static void DictionaryProcessing(string[] emailIDs)
        {
            List<Product> products = new List<Product>();

            Product product1 = new Product() { Name = "Pencil", Days = 14 };
            Product product2 = new Product() { Name = "Eraser", Days = 2 };
            Product product3 = new Product() { Name = "Geometry Box", Days = 31 };

            products.Add(product1);
            products.Add(product2);
            products.Add(product3);

            Dictionary<string, Dictionary<Roles, Dictionary<Period, List<Product>>>> dict = new Dictionary<string, Dictionary<Roles, Dictionary<Period, List<Product>>>>();

            ///

            foreach (string emailID in emailIDs)
            {

                if (!dict.ContainsKey(emailID))
                    dict.Add(emailID, new Dictionary<Roles, Dictionary<Period, List<Product>>>());

                if (!dict[emailID].ContainsKey(Roles.Preparer))
                    dict[emailID].Add(Roles.Preparer, new Dictionary<Period, List<Product>>());

                if (!dict[emailID][Roles.Preparer].ContainsKey(Period.Ahead))
                    dict[emailID][Roles.Preparer].Add(Period.Ahead, new List<Product>());

                if (!dict[emailID][Roles.Preparer].ContainsKey(Period.Past))
                    dict[emailID][Roles.Preparer].Add(Period.Past, new List<Product>());

                ///

                if (!dict[emailID].ContainsKey(Roles.Approver))
                    dict[emailID].Add(Roles.Approver, new Dictionary<Period, List<Product>>());

                if (!dict[emailID][Roles.Approver].ContainsKey(Period.Ahead))
                    dict[emailID][Roles.Approver].Add(Period.Ahead, new List<Product>());

                if (!dict[emailID][Roles.Approver].ContainsKey(Period.Past))
                    dict[emailID][Roles.Approver].Add(Period.Past, new List<Product>());

                for (int i = 0; i < products.Count; i++)
                {
                    dict[emailID][Roles.Preparer][Period.Ahead].Add(products[i]);
                    dict[emailID][Roles.Preparer][Period.Past].Add(products[i]);
                    dict[emailID][Roles.Approver][Period.Past].Add(products[i]);
                    dict[emailID][Roles.Approver][Period.Ahead].Add(products[i]);
                }


            }
        }
    }
}
`

如何按此順序排序? 我僅限於使用.NET 2.0框架。

字典無法排序。 它們不是列表。 另外:

您的結構不好- Dictionary不能多次包含相同的鍵,因此您提供的樣本甚至無法創建:

"Sachin" --> Roles.Preparer --> Period.Past --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products
"Sachin" --> Roles.Approver --> Period.Past --> Products

“外部”詞典不能多次包含鍵“ Sachin”。 “內部詞典”不能多次包含“ Approver ”角色,並且在最后一個級別Period.Past/Ahead上不能多次包含鍵。

相反,將您的結構更改為List<T> ,其中T是適當的數據結構,或者,正如其他人已經指出的那樣,現在更改為類型化數據集以將您的結構像表一樣對待。

編輯
我現在正在編輯我的答案,以確保我們都了解每個人在說什么。

我的意思是,字典不可能兩次具有相同的鍵。 因此,根據此規則,您的案件必須減少到以下情況:

"Sachin" --> Roles.Preparer --> Period.Past --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products
"Sachin" --> Roles.Approver --> Period.Past --> Products

現在,我們正在討論適用於規則的內容,我們可以問“如何排序?”。 答案:你不能。 根據定義,字典是無序結構。 但是,您可以確保按特定順序檢索值。 如果您要對產品進行“分類”,以使“ Past產品始終在“ Ahead產品之前,請確保首先使用相應的密鑰。

編輯2

剛剛意識到這是基於復制/粘貼錯誤。 您正在談論的數據應為:

"Sachin" --> Roles.Preparer --> Period.Ahead --> Products
"Sachin" --> Roles.Preparer --> Period.Past --> Products
"Sachin" --> Roles.Approver --> Period.Past --> Products
"Sachin" --> Roles.Approver --> Period.Ahead --> Products

您說您正在使用此代碼添加項目:

for (int i = 0; i < products.Count; i++)
{
    dict[emailID][Roles.Preparer][Period.Ahead].Add(products[i]);
    dict[emailID][Roles.Preparer][Period.Past].Add(products[i]);
    dict[emailID][Roles.Approver][Period.Past].Add(products[i]);
    dict[emailID][Roles.Approver][Period.Ahead].Add(products[i]);
}

然后,您可以使用類似的代碼來檢索項目。 給定一個電子郵件ID,以下內容將為您提供按“批准前准備”和“先粘貼”順序排列的項目列表:

List<Product> productsForEMailID = new List<Product>();

productsForEMailID.AddRange(dict[emailID][Roles.Preparer][Period.Past]);
productsForEMailID.AddRange(dict[emailID][Roles.Approver][Period.Past]);
productsForEMailID.AddRange(dict[emailID][Roles.Preparer][Period.Ahead]);
productsForEMailID.AddRange(dict[emailID][Roles.Approver][Period.Ahead]);

產品列表是“已排序”的。

您可以使用另一種類型的密鑰,它更適合此問題。 如果您想快速破解SortedDictionary<string, List<Product>>

"Sachin#0#0" --> Products
"Sachin#0#1" --> Products
...

在這里,我假設名稱中不能出現'#'字符。 第一個數字代表RolesPreparer = 0 Approver = 1 Preparer = 0Approver = 1 ,第二個數字代表Period ,代表Ahead = 0Past = 1

或者-如果您需要一個更強大的解決方案,我將提供以下信息:

public struct Key : IComparable<Key>
{
    public String Name;
    public Roles Role;
    public Period Period;

    public int CompareTo(Key other)
    {
        var c = String.Compare(Name, other.Name, StringComparison.Ordinal);
        if (c != 0) return c;
        c = Role.CompareTo(other.Role);
        if (c != 0) return c;
        return Period.CompareTo(other.Period);
    }
}

...並使用SortedDictionary<Key, List<Product>>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM