数据结构 - 对于多种可能的键类型,如果key为true,则返回值的子集

时间:2012-11-27 19:12:47

标签: c# data-structures

一个简单的例子:

Tom, Mary and John say "I want an apple"
Tom and John say "I want a race car"
John and Mary say "I want a pretty dress."

DataStructure[Tom] returns --> "I want an apple";"I want a racecar";
DataStructure[Mary] returns --> "I want an apple";"I want a pretty dress";

什么是数据结构?如果键或值的数量可以改变?我可以在哪里键入DataStructure.Add(Mary,“New String);或DataStructure.AddWithNewKey(”Timmy“,List)?


有没有比为每个人保留一个列表或字符串数​​组更好的方法?


在下面的评论中,我很困惑,如果数据在编译时已知或纯粹是动态的,为什么会这么重要。 Jon已经指出,如果要动态构建数据,理想的是将字符串值与人们相关联的字典。否则他的linq解决方案非常好。

1 个答案:

答案 0 :(得分:2)

听起来你想要ILookup - 从键到多个值的映射。您可以使用LINQ中的ToLookup方法创建它。或者,如果您想以可变的方式构建类似的东西,可以使用Dictionary<,>,其中的类型是某种类型的列表,例如Dictionary<string, IList<string>>。这比使用查找更加繁琐,并且对于丢失密钥的行为并不优雅。

最好的解决方案部分取决于您获取数据的方式,请注意。你的例子并不是很清楚。

编辑:你不想要Lookup<bool, StringInfo>。您需要Lookup<Person, string>其中PersonTomMaryJohn或类似内容的枚举。这些被硬编码为属性的事实很尴尬,但并非不可克服。我会添加一个这样的实用方法:

static IEnumerable<Person> GetPeople(StringInfo input)
{
    // I don't normally use this formatting, but it's cleaner than the
    // alternatives in this particular case.
    if (input.Mary) yield return Person.Mary;
    if (input.Tom) yield return Person.Tom;
    if (input.John) yield return Person.John;
}

然后您可以使用:

var lookup = allStringInfos
       .SelectMany(info => GetPeople(info),
                   (info, person) => new { text = info.stringInfo, person })
       .ToLookup(pair => pair.person,
                 pair => pair.text);

然后:

foreach (string value in lookup[Person.John])
{
    ...
}