c#嵌套字典,更好的选择?最好在三个班级组织数据 [英] c# Nested Dictionary, better alternative? best organize data across three classes

查看:107
本文介绍了c#嵌套字典,更好的选择?最好在三个班级组织数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设



有一个Trend类。

  public趋势趋势{
public string TrendName {get; set;}
public string说明{get; set;}
}

例如

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

class。

  public class Person {
public string PersonName {get;}
public int PersonId {get ;}
public int aptitude {get;}
......许多其他属性
}

例如

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

有一个事情类。 p>

  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)输入:Person;输出:人们对时尚项目的选择列表。



2)输入:趋势;输出:属于该趋势的时尚商品列表。



我已经考虑过两种方式。



A)字典< Person,Dictionary< Trend,TrendyItem>>



您可以获得PersonsChoiceOnTrendyItem = dic [Person] .Values.ToList();



,但必须循环并构建新列表,每次你看



B)字典<趋势,字典< Person,TrendyItem>>



副词。



将这些自定义对象用于字典键是一个好习惯吗?



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



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



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






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

解决方案

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



而不是嵌套字典,您应该考虑将集合添加到对象。例如,您可以将列表< TrendyItem> 添加到趋势以维护该关系。



这是您可以组织课程的另一种方法。我不确定每个收藏的范围是多少,但这应该是另一种方式来查看问题。

  public class Trend 
{
public string TrendName {get;组; }
public string描述{get;组; }

//维护Trend和TrendyItem之间的关系
public List< TrendyItem>物品{get;组; }
}

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

//每个人都会指定一个TrendyItem
public TrendyItem Choice {get;组; }
}

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

public class TrendProfile
{
//将其更改为键值对。关键是您如何唯一识别(输入)
//中的趋势图2)输入:趋势;输出:属于该趋势的时尚项目列表。
//例如TrendName
public Dictionary< string,Trend> FavoriteTrendsOfYear;

//将其更改为键值对。关键是你如何唯一识别(输入)
//中的Person 1)Input:Person;输出:人物对时尚项目的选择列表。
//例如PersonName
public Dictionary< string,Person> ActivePeopleThisYear;


public List< TrendyItem> TrendyItemsThisYear;
}

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

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

trendProfile.FavoriteTrendsOfYear =新词典< string,Trend> {
{Pizza,new Trend(){
TrendName =Pizza,
描述=yum yum,
Items = new List< TrendyItem& {
new TrendyItem(){ItemName =PotatoPizza1},
new TrendyItem(){ItemName =PotatoPizza2},
new TrendyItem(){ItemName =PotatoPizza3}
$
{衣服,新趋势(){
TrendName =服装,
描述=ba yum,
项目=新列表<趋势项> {
new TrendyItem(){ItemName =PeplumSkirt1},
new TrendyItem(){ItemName =PeplumSkirt2},
new TrendyItem(){ItemName =PeplumSkirt3}
}
}}
};

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

// 1)输入:Person;输出:人物对时尚项目的选择列表。
string person =Arnold Palmer;
Console.WriteLine(trendProfile.ActivePeopleThisYear [person] .Choice.ItemName);

// 2)输入:趋势;输出:属于该趋势的时尚项目列表。
string trend =服装;
foreach(trendyItem item in trendProfile.FavoriteTrendsOfYear [trend] .Items)
Console.WriteLine(item.ItemName);

}

更新

要共享TrendProfiles中的趋势,您可以先创建一个master列表 Dictionary 趋势。然后,当构建每个TrendProfliles时,您可以从主中选择趋势。

  //主列表趋势
列表<趋势> trends =新列表<趋势> {
new Trend(){
TrendName =Pizza,
描述=yum yum,
Items = new List< TrendyItem> {
new TrendyItem(){ItemName =PotatoPizza1},
new TrendyItem(){ItemName =PotatoPizza2},
new TrendyItem(){ItemName =PotatoPizza3}
}
},
new Trend(){
TrendName =服装,
描述=ba yum,
Items = new List< TrendyItem& {
new TrendyItem(){ItemName =PeplumSkirt1},
new TrendyItem(){ItemName =PeplumSkirt2},
new TrendyItem(){ItemName =PeplumSkirt3}
}
}
};


TrendProfile trendProfile1 = new TrendProfile();

trendProfile1.FavoriteTrendsOfYear =新词典< string,Trend> {
{trends [0] .TrendName,trends [0]},
{trends [1] .TrendName,trends [1]}
};

TrendProfile trendProfile2 = new TrendProfile();

trendProfile2.FavoriteTrendsOfYear =新词典< string,Trend> {
{trends [1] .TrendName,trends [1]}
};


Suppose

There is a Trend class.

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

e.g.

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

There is a Person class.

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

e.g.

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

There is a thing class.

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

e.g.

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

There is a TrendysOfYear class. This class already has.

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

For every TrendysOfYear, There will be a list of different trends, FavoriteTrendsOfYear,

each person belonging to the ActivePeopleThisYear

will specifiy a "TrendyItem"

Given a TrendProfile, I want to be able to be able to quickly look up

1) Input: Person; Output: List of Person's choice on trendy items.

2) Input: Trend; Output: List of trendy items belonging to that trend.

I've considered two ways.

A) Dictionary<Person, Dictionary<Trend, TrendyItem>>

You can get PersonsChoiceOnTrendyItem = dic[Person].Values.ToList();

but have to loop through and build new list everytime you look up TrendyItemsOfTrend.

B) Dictionary<Trend, Dictionary<Person, TrendyItem>>

vice cesra.

Is it a good practice to use these custom objects for dictionary keys?

Is it a good practice to use nested dictionaries?

What's the best way to map items in this case?

Also, not that Trend class does not have integer Id, so will have to used the string (the name of the trend is guaranteed to be unique) as key.


Additional Info: properties of Trend such as TrendName and Description are editable. So i'm a little hesitant to add collection of TrendyItems to Trend class. If there is Trend, "Fashionn" in TrendProfile1 and TrendProfile2, and someone decides to change the name to "Fashion", I want both profiles to reference the same object.

解决方案

Typically you don't see the objects that contain values used as keys in this way. Usually you will identify some unique key on your object and use that as key and the object itself as the value. For example you could store Person objects in a Dictionary where the person's name is the key, and Person is the value.

Instead of nested Dictionaries, you should consider adding Collections to your objects. For example, you could add a List<TrendyItem> to Trend to maintain that relationship.

Here is an alternative way that you could organize the classes. I'm not exactly sure what the scope is of each of your collections, but this should give you another way to look at the problem.

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; 
}

With that class structure, you can easily answer the questions in your post.

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);

}

UPDATE

To share Trends across TrendProfiles, you could first create a "master" List or Dictionary of Trends. Then when building each of the TrendProfliles, you could pick the Trends out of the "master".

// "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] }
};

这篇关于c#嵌套字典,更好的选择?最好在三个班级组织数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆