【问题标题】:c# Nested Dictionary, better alternative? best organize data across three classesc#嵌套字典,更好的选择?最好地跨三个类组织数据
【发布时间】:2014-07-11 23:58:57
【问题描述】:

假设

有一个趋势类。

public class Trend{ 
    public string TrendName { get; set; }
    public string Description { get; set; }
}

例如

new Trend() { TrendName= "Pizza", Description="yum yum" };
new Trend() { TrendName= "Clothing", Description="ba yum" };
new Trend() { TrendName= "Food" };

有一个 Person 类。

public class Person { 
    public string PersonName { get; }
    public int PersonId { get; }
    public int aptitude { get; }
    ...... many other properties
}

例如

new Person() { PersonName = "Arnold Palmer" };
new Person() { PersonName = "Ken Hemingway" };

有一个东西类。

public class TrendyItem
{
    public string ItemName { get; }
    public string ItemId { get; }
}

例如

new TrendyItem() { ItemName = "PotatoPizza" }
new TrendyItem() { ItemName = "PeplumSkirt" }

有一个 TrendysOfYear 类。这个类已经有了。

public class TrendProfile
{
    public List<Trend> FavoriteTrendsOfYear;
    public List<Person> ActivePeopleThisYear;
    public List<TrendyItem> TrendyItemsThisYear;    
}

对于每一个 TrendysOfYear, 会有一个不同趋势的列表,FavoriteTrendsOfYear,

属于 ActivePeopleThisYear 的每个人

将指定一个“TrendyItem”

给定一个 TrendProfile,我希望能够快速查找

1) 输入:人;输出:个人对流行物品的选择列表。

2) 输入:趋势;输出:属于该趋势的流行物品列表。

我考虑了两种方法。

A)Dictionary&lt;Person, Dictionary&lt;Trend, TrendyItem&gt;&gt;

你可以得到 PersonsChoiceOnTrendyItem = dic[Person].Values.ToList();

但每次查找 TrendyItemsOfTrend 时都必须循环并构建新列表。

B)Dictionary&lt;Trend, Dictionary&lt;Person, TrendyItem&gt;&gt;

副题。

将这些自定义对象用作字典键是否是一种好习惯?

使用嵌套字典是个好习惯吗?

在这种情况下,映射项目的最佳方式是什么?

另外,不是Trend类没有整数Id,所以必须使用字符串(保证趋势的名称是唯一的)作为key。


附加信息:TrendName 和Description 等Trend 属性是可编辑的。所以我有点犹豫是否将 TrendyItems 集合添加到 Trend 类。如果 TrendProfile1 和 TrendProfile2 中存在 Trend、“Fashionn”,并且有人决定将名称更改为“Fashion”,我希望两个配置文件都引用同一个对象。

【问题讨论】:

  • 当你想在一年中添加一件时髦单品时,它总是与一个人联系在一起吗?也就是说,当年的比萨名单是由人们挑选的所有当年流行的比萨组成的吗?还是先列出比萨饼,然后人们从该列表中投票?
  • 另外,每个人是只选择一种趋势,还是可以选择多种?
  • 是:“由人们挑选的当年流行的所有披萨组成的年度披萨列表”,每个人可以根据趋势选择一个或NULL。

标签: c# dictionary


【解决方案1】:

通常,您不会看到包含以这种方式用作键的值的对象。通常你会在你的对象上识别出一些唯一的键,并将其用作键,将对象本身用作值。例如,您可以将 Person 对象存储在 Dictionary 中,其中人名是键,Person 是值。

您应该考虑将集合添加到您的对象中,而不是嵌套字典。例如,您可以将List&lt;TrendyItem&gt; 添加到Trend 以保持这种关系。

这是组织课程的另一种方式。我不确定你的每个集合的范围是什么,但这应该会给你另一种看待问题的方式。

public class Trend
{
    public string TrendName { get; set; }
    public string Description { get; set; }

    // This maintains the relationship between Trend and TrendyItem
    public List<TrendyItem> Items { get; set; }
}

public class Person
{
    public string PersonName { get; set; }
    public int PersonId { get; set; }
    public int aptitude { get; set; }

    // Each person will specifiy a "TrendyItem"
    public TrendyItem Choice { get; set; }
}

public class TrendyItem
{
    public string ItemName { get; set; }
    public string ItemId { get; set; }
}

public class TrendProfile
{
    // Change this to to a key value pair. The key will be how you uniquely identify (input) the Trend in
    //2) Input: Trend; Output: List of trendy items belonging to that trend.
    // For example TrendName
    public Dictionary<string, Trend> FavoriteTrendsOfYear;

    // Change this to to a key value pair. The key will be how you uniquely identify (input) the Person in
    // 1) Input: Person; Output: List of Person's choice on trendy items.
    // For example PersonName
    public Dictionary<string, Person> ActivePeopleThisYear;


    public List<TrendyItem> TrendyItemsThisYear; 
}

使用该类结构,您可以轻松回答帖子中的问题。

static void Main()
{
    TrendProfile trendProfile = new TrendProfile();

    trendProfile.FavoriteTrendsOfYear = new Dictionary<string, Trend> {        
        { "Pizza", new Trend() {
            TrendName = "Pizza",
            Description = "yum yum",
            Items = new List<TrendyItem> {
                new TrendyItem() {ItemName = "PotatoPizza1"},
                new TrendyItem() {ItemName = "PotatoPizza2"},
                new TrendyItem() {ItemName = "PotatoPizza3"}
            }
        }},
        { "Clothing", new Trend() {
            TrendName = "Clothing",
            Description = "ba yum",
            Items = new List<TrendyItem> {
                new TrendyItem() {ItemName = "PeplumSkirt1"},
                new TrendyItem() {ItemName = "PeplumSkirt2"},
                new TrendyItem() {ItemName = "PeplumSkirt3"}
            }
        }}
    };

    trendProfile.ActivePeopleThisYear = new Dictionary<string, Person> {
        { "Arnold Palmer", new Person() { PersonName = "Arnold Palmer", Choice = trendProfile.FavoriteTrendsOfYear["Pizza"].Items[1] }},
        { "Ken Hemingway", new Person() { PersonName = "Ken Hemingway", Choice = trendProfile.FavoriteTrendsOfYear["Clothing"].Items[2] }},
    };

    //1) Input: Person; Output: List of Person's choice on trendy items.
    string person = "Arnold Palmer";
    Console.WriteLine(trendProfile.ActivePeopleThisYear[person].Choice.ItemName);

    //2) Input: Trend; Output: List of trendy items belonging to that trend.
    string trend = "Clothing";
    foreach(TrendyItem item in trendProfile.FavoriteTrendsOfYear[trend].Items)
        Console.WriteLine(item.ItemName);

}

更新

要跨 TrendProfiles 共享趋势,您可以首先创建趋势的“主”ListDictionary。然后在构建每个 TrendProfiles 时,您可以从“master”中选择 Trends。

// "Master" list of trends
List<Trend> trends = new List<Trend> {
    new Trend() {
        TrendName = "Pizza",
        Description = "yum yum",
        Items = new List<TrendyItem> {
            new TrendyItem() {ItemName = "PotatoPizza1"},
            new TrendyItem() {ItemName = "PotatoPizza2"},
            new TrendyItem() {ItemName = "PotatoPizza3"}
        }
    },
    new Trend() {
        TrendName = "Clothing",
        Description = "ba yum",
        Items = new List<TrendyItem> {
            new TrendyItem() {ItemName = "PeplumSkirt1"},
            new TrendyItem() {ItemName = "PeplumSkirt2"},
            new TrendyItem() {ItemName = "PeplumSkirt3"}
        }
    }
};


TrendProfile trendProfile1 = new TrendProfile();

trendProfile1.FavoriteTrendsOfYear = new Dictionary<string, Trend> {        
    { trends[0].TrendName, trends[0] },
    { trends[1].TrendName, trends[1] }
};

TrendProfile trendProfile2 = new TrendProfile();

trendProfile2.FavoriteTrendsOfYear = new Dictionary<string, Trend> {
    { trends[1].TrendName, trends[1] }
};

【讨论】:

  • 感谢您的建议。我忘了提到“Trend”类可以在不同的“TrendProfile”类中重用。如果趋势相同,我希望两个配置文件都引用同一个对象。有什么好的方法可以做到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2019-04-02
  • 1970-01-01
相关资源
最近更新 更多