我有一个字典对象,其类型如下所示。
Dictionary<string, Dictionary<Roles, Dictionary<Period, List<Product>>>>
具有“准备者”的角色(是一个枚举)&amp; “批准者”作为他们的项目。同样期间是另一个具有“未来”和“未来”的枚举。 “过去”的项目。
列表包含各种产品的列表。
我在字典中有以下层次结构的项目。
"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框架。
答案 0 :(得分:1)
无法对字典进行排序。它们不是列表。此外:
您的结构不好 - 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]);
}
然后您可以使用类似的代码来检索项目。给定一个eMail-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]);
产品列表已“排序”。
答案 1 :(得分:0)
您可以使用其他类型的密钥,更适合此问题。如果你想快速破解SortedDictionary<string, List<Product>>
:
"Sachin#0#0" --> Products
"Sachin#0#1" --> Products
...
这里我假设'#'字符不能出现在名称中。第一个数字代表Roles
Preparer = 0
,Approver = 1
,第二个数字代表Period
Ahead = 0
,Past = 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>>
。