可以说我有一个对象,它有stringProp1,stringProp2。我希望将stringProp1,stringProp2的每个组合存储在Dictionary中。最初,我将密钥存储为key = stringProp1 + stringProp2,但实际上这可能会导致一个错误,具体取决于2个值。对于这个问题来说,创建自定义字典类还是有更好的方式使用内置的.NET类是最好的解决方案吗?散列表/字典,但键与多个值组成?
回答
这不要紧,你的关键,只要钥匙适用于一个比较器,以正确比较/哈希必要的信息,使用什么数据结构。
您甚至可以将您的对象用作字典中的键,并将您喜欢的任何字段与适当的EqualityComparer
实现进行比较。这其中用序号比较两个String属性比较了:
class MyObject
{
public string StringProp1 { get; set; }
public string StringProp2 { get; set; }
public MyObject(string prop1, string prop2)
{
StringProp1 = prop1;
StringProp2 = prop2;
}
}
class MyObjectComparerS1S2 : EqualityComparer<MyObject>
{
//Change this if you need e.g. case insensitivity or
//culture-specific comparisons
static StringComparer comparer = StringComparer.Ordinal;
public override bool Equals(MyObject x, MyObject y)
{
return
comparer.Equals(x.StringProp1, y.StringProp1) &&
comparer.Equals(x.StringProp2, y.StringProp2);
}
public override int GetHashCode(MyObject obj)
{
//Uncomment this if running in a checked context
//Copycat of Jon Skeet's string hash combining
//unchecked
//{
return
(527 + comparer.GetHashCode(obj.StringProp1)) * 31 +
comparer.GetHashCode(obj.StringProp2);
//}
}
public static readonly MyObjectComparerS1S2 Instance =
new MyObjectComparerS1S2();
}
static void Main(string[] args)
{
Dictionary<MyObject, MyObject> dict =
new Dictionary<MyObject, MyObject>(MyObjectComparerS1S2.Instance);
MyObject obj = new MyObject("apple", "plum");
dict.Add(obj, obj);
MyObject search = new MyObject("apple", "plum");
MyObject result = dict[search];
Console.WriteLine("{0}:{1}", result.StringProp1, result.StringProp2);
}
可以通过创建虚拟之一,在字符串键填充和使用虚拟作为查找密钥搜索对象。 如果你不喜欢这个想法,或者这是不可行的,只要按照@Vlad的说法提取结构或类中的键即可。在这种情况下,修改比较器以从EqualityComparer<MyKeyStructOrClass>
派生。
请注意,我用Jon Skeet's method来组合字符串散列。这可能比XOR method found on MSDN更好。如果你觉得它是钢铁不足的话,可以随意用另一个散列实现来对待字符串 - Hsieh,Murmur,Bob Jenkin's,或者你认为的任何东西。下面是一个nice page about hash functions,它实际上也有一些C#代码。
如果有一个字符不会出现在任何一个字符串中,您可以在其中放置一个分隔符。
如
stringProp1 + "|" + stringProp2
如果没有,那么我建议Dictionary<string, Dictionary<string, MyValueType>>
在
var dictionary = new Dictionary<string, Dictionary<string, MyValueType>>();
// .... Do stuff
if (!dictionary.ContainsKey(stringProp1))
dictionary.Add(stringProp1, new Dictionary<string, MyValueType>());
dictionary[stringProp1][stringProp2] = myValue;
可以使用MD5算法来产生一个值为每个字符串,然后总结两个值。结果是关键。
.NET在System.Security.Cryptography命名空间中提供类MD5CryptoServiceProvider。该类包含ComputeHash方法来计算散列值。
这不可靠。如果字符串是随机的,则1/2^128的概率是md5散列将会发生冲突。这将会非常缓慢。 – Vlad 2010-03-02 21:28:11
为什么不只是使用一个结构与2个字符串作为关键?这将是最简单的。
在.NET 4中,您可以使用System.Tuple
作为关键。
var dict = new Dictionary<Tuple<string,string>, int>();
dict.Add(Tuple.Create("foo","bar"), 1);
如果你想在早期版本的.NET中使用它,你也可以引用FSharp.Core。 – 2010-03-05 01:14:50
你也可以使用.Net 3.5中的keyvaluepair作为新的字典
根据填充词典的方式以及使用它的方式,可以使用匿名类型作为键。例如,如果你有一个类Person
:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
如果你有这些的IEnumerable<Person>
序列,并希望创建一个映射名年龄字典,你可以写:
var personDictionary = people.ToDictionary(p => new { p.FirstName, p.LastName });
这会为您提供一个名字和姓氏为字典的字典,并将整个Person
作为值存储。您可以在以后查找用钥匙:
personDictionary.TryGetValue(new { FirstName = "John", LastName = "Smith" },
out person);
这不会有助于帮助你多,如果你想通过不同的课程或甚至方法之间的字典,它变得难以管理,但做一些以单一方法快速处理数据,效果很好。事实上,使用匿名类作为GroupBy
扩展方法或group by
查询理解语法的关键字很常见。
- 1. UpdateModel与字典/散列表
- 2. 带有多个键值的散列表?
- 3. 按键和值组合多个字典?
- 4. 按多个键分组,汇总/平均多个字典列表的值
- 5. 将字典值绘制成多行/时间序列散景图
- 6. 获得在Matlab与字典键的列表值列表
- 7. Python字典与列表关键字
- 8. Python:获取与字典中单个键关联的值列表
- 9. 如何将字典与键值合并但包含多个不同的列表值?
- 10. 词典键(C#)字典组列表字典
- 11. 将两个列表组合成一个字典,其中的值与单个(并且经常重复)键相关
- 12. 用C#将多个字节[]一起散列成单个散列?
- 13. 具有多个值和一个键的Powershell散列表
- 14. 列表键值对到字典
- 15. 将列表值添加到字典键
- 16. 键入字典:值为列表
- 17. 如何将多个散列值的数组中有相同键
- 18. Python:为字典键添加多个值
- 19. 如何给字典值多个键?
- 20. 添加独特的键值散列和创建字典出它
- 21. 以字典列表作为键和元组作为值的Python字典
- 22. Python字典和字典的列表中的键的平均值
- 23. 写一个字典列表,每个键的多个值作为新行
- 24. 列表到字典与键是一个字符串计数器
- 25. PYTHON:属性值对拆分列表分为多键字典
- 26. Python:存储与字典中的键相关联的列表值
- 27. 哪个字典或散列表的键可以是符号表达式?
- 28. 更新字典与另一个字典,但只有非无值
- 29. 两个列表成为一个字典
- 30. 一行到列表返回第一个字典字典键的值,它包含另一个关键价值
这不起作用。 “blah |”,“blah”和“blah”,“| blah”这对组合如何?你需要小心。 – Keltex 2010-03-02 21:14:03