繁体   English   中英

馆藏集合VS C#馆藏字典?

[英]Collection of Collections VS Dictionary of Collections in C#?

情况:我需要传递一组对象,然后对它们进行分组。 我知道我可以为此使用LINQ。

但是,如果我自己做的话, 让我的方法返回“收藏集VS收藏集字典”之间是否有任何偏好? 我知道Dictionary也是一个集合,但是它引入了key参数。

  • 返回的对象的预期用途是使用For Each语句按组显示。
  • 原始收藏集中的平均数量约为20,因此性能不是问题。

提前致谢。

总结评论:

  • 如果您确实需要查找特定项目,请执行以下操作: Dictionary =>因为查找时间为O(1)
  • 如果您只需要遍历所有项目:两者都可以,因为两种情况下的查找时间均为O(n)

如果您想向用户展示内容,并且说您愿意,那么Dictionary几乎肯定是错误的方法。 Dictionary没有可预测的顺序。 按照从Dictionary中检索它们的顺序显示Dictionary中的Dictionary是没有意义的。

如果键的顺序与项目的预期顺序匹配,则始终按键值排序的SortedDictionarySortedList可能是合适的。

但是否则,只需使用常规数组/ List / Collection ,您就可以在其中手动按照所需的顺序手动放置项目。

您已经发布了一个相当模糊的问题,但让我们继续进行讨论,使其更加具体。 假设您有一个此类的集合:

public class MyItem
{
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime OrderDate { get; set; }
}

并且您有一个将其分组的方法(以及可选的过滤器,...执行其他操作),如下所示:

public RETURNTYPE ProcessItemGroupedByOrderDate(IEnumerable<MyItem> items);

那应该按OrderDate属性分组。

您的问题是:

在让我的方法返回“收藏集”与“收藏字典”之间是否有任何偏好? 返回的对象的预期用途是使用For Each语句按组显示。

RETURNTYPE应该是

  • IDictionary<DateTime, ICollection<MyItem>>
  • ICollection<ICollection<MyItem>>

其中ICollection表示任何合适的集合类型( IEnumerableIList ,...)。

我的答案是:让客户决定。 如果您返回分组,则让返回类型为:

IEnumerable<IGrouping<DateTime, MyItem>>

除了一个明显的决定点,即是否需要按照某些标准(如Dictionary所提供的那样)对外部集合进行索引,通常只是每个外部项目需要多少信息。

在频谱的一端,每个外部项目都没有与之关联的元数据。 外部列表中的每个项目只是一个集合,没有标识信息。 例如,如果您按学生所在的宿舍对学生列表进行了分组,那么在遍历列表时,您会知道所有这组学生都属于同一个宿舍,但是您不知道哪个宿舍基于仅在您的列表中。

频谱的中间是带有原始键的字典。 现在,您可以获得每个嵌套列表KeyValuePair Key的信息。 该密钥可能是标识宿舍的某种唯一ID。

频谱的另一端是无限的元数据。 您为外部列表中的项目定义一个类,并且该项目的属性是一个集合:

class Dorm {

  public int DormID {get;set;}
  public string DormName {get;set;}
  public Gender DormPermittedGender {get;set;}
  public List<Person> Students {get;set;}
}

class Person {
  public string Name {get;set;}
  public Gender Gender {get;set;}
  public int Age{get;set;}
}

///...
List<Dorm> dorms = db.Dorms.Select(d=> 
  new Dorm {
     DormId = d.Id,
     DormName = d.Name,
     DormPermittedGender = d.PermittedGender,
     Students = d.StudentsResiding
  }
)

foreach(Dorm dorm in dorms)
{
   foreach(Person student in dorm.Students)
   {
      Console.Writeline(student.Name + " lives in " + dorm.DormName);
   }
}

注意foreach的可读性。 没有神秘的钥匙。

现在,词典实际上可以做到这一点,因为您可以将复杂的对象作为键,但是它的组织性不强。 如果情况需要,强类型对象将更好地表示这种关系。

过度使用列表或字典列表会使代码难以阅读,因为没有自我描述的属性名称。 您遇到了一些旧的代码,并且不得不四处寻找首先分配了Dictionary以确定Key含义的位置,因为您所拥有的只是类型,它是一个不传达语义的int

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM