【问题标题】:What C# data structure should I use to map a varying number of key/value pairs to a list of strings?我应该使用什么 C# 数据结构将不同数量的键/值对映射到字符串列表?
【发布时间】:2011-02-17 05:36:59
【问题描述】:

假设我想要一份我附近所有地址的列表。如果他们住在任何地址,我还想关联朋友的姓名和电话号码。但并非每个地址都有一个朋友住在那里,因为许多地址都住着完全陌生的人,但相反,可能不止一个朋友住在一个地址。

总而言之,对于住在这些地址的任何朋友,我既需要地址列表,也需要以姓名/电话# 对的形式关联到所有这些字符串。搜索此数据的索引仅为地址,我不需要通过姓名或电话号码访问信息,但如果地址有朋友住在那里,我想遍历该数据。

在这种情况下使用的最佳 C# 数据结构是什么,您能否给我一些示例代码来展示它的实现?非常感谢。

【问题讨论】:

    标签: c# data-structures key-value


    【解决方案1】:

    Dictionary 类是您的最佳选择。即使您可以使用本机 KeyValuePair 或 Tuple 类之一,我也会创建一个帮助类来存储 Name/Phone # 键值对。最后,代码如下所示:

    class ContactInfo
    {
       string Name;
       string TelephoneNumber;
    }
    
    Dictionary<string, ICollection<ContactInfo>> addressAndPeopleLivingThere = 
        new Dictionary<string, ICollection<ContactInfo>>();
    
    addressAndPeopleLivingThere.Add("1 Some Street", new List<ContactInfo>());
    addressAndPeopleLivingThere["1 Some Street"].Add(new ContactInfo { Name = "Name", TelephoneNumber = "000-000-0000" });
    

    【讨论】:

    • 我如何遍历每个 ContactInfo 类的属性,例如将它们的值输出到控制台?我对字典的键执行此操作没有问题,但是我正在创建的每个类呢?这就是我得到的键: foreach (KeyValuePair> kvp in addressAndPeopleLivingThere { Console.WriteLine(kvp.Key); }
    • kvp.Value 返回与该键关联的 ContactInfo 对象,因此 kvp.Value.Name 和 kvp.Value.TelephoneNumber 让您可以访问这些属性
    【解决方案2】:

    您应该创建代表您的域的类型。 比如:

    public class Address{
      public string StreetName{get;set;}
      public List<Person> Friends{get;set;}
    }
    public class Person{
       public string Name{get;set;}
       public string Phone{get;set;}
    }
    

    然后你在列表中操作。

    List<Address> addresses = new List<Address>;
    
        var addWithFriends = from c in addresses where c.Count > 0 select c;
    

    【讨论】:

      【解决方案3】:

      您可能需要ILookup&lt;string, Friend&gt;Dictionary&lt;string, IEnumerable&lt;Friend&gt;&gt;,它们基本上是相同的。由于要包含所有地址,因此构造会比简单的ToDictionaryToLookup 复杂一点,但也不算太糟糕:

      var friendsByAddress = friends.ToLookup(f => f.Address);
      var addressesWithFriends = addresses.ToDictionary(
          a => a,
          a => !friendsByAddress.Contains(a) ? Enumerable.Empty<Friend>() : friendsByAddress[a]);
      

      使用它很简单:

      var friendsAtAddress = addressesWithFriends[address];
      foreach(var friend in friends) 
      {
          ...
      }
      

      【讨论】:

      • @soster:小心! LINQ 令人上瘾。一旦你开始使用它,你就会一直想知道没有它的人是如何编程的。 ;-)
      猜你喜欢
      • 2016-12-08
      • 2017-10-27
      • 2011-10-24
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2012-11-04
      • 2019-11-13
      • 1970-01-01
      相关资源
      最近更新 更多