可以說我有一個對象,它有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. 如何從兩個列表中生成字典,具有多個值的鍵
- 7. 列表,字典,每個鍵
- 8. Python:從一個嵌套列表中的多個值的元組鍵的字典
- 9. 獲得在Matlab與字典鍵的列表值列表
- 10. Python字典與列表關鍵字
- 11. Python:獲取與字典中單個鍵關聯的值列表
- 12. 怎麼做我就與值的兩個字典鍵爲列表
- 13. 將一個字典的鍵與一個值列表比較一個字典到另一個字典
- 14. 如何將字典與鍵值合併但包含多個不同的列表值?
- 15. 按多個鍵進行分組並彙總字典列表的平均值
- 16. 2d字典,每個值有多個鍵
- 17. C#字典,每個鍵有多個值
- 18. 轉換文件成一個字典,一個鍵和多個值
- 19. 將兩個列表組合成一個字典,其中的值與單個(並且經常重複)鍵相關
- 20. 將一個散列鍵與其他散列值進行比較
- 21. 從字典的列表轉換一個關鍵字值列出
- 22. 用C#將多個字節[]一起散列成單個散列?
- 23. 將多個值列表映射到python字典中的鍵列表?
- 24. 具有多個值和一個鍵的Powershell散列表
- 25. C本地支持每個鍵多個值的散列表庫
- 26. 將列表值添加到字典鍵
- 27. 字典鍵值,以選擇列表
- 28. 列表鍵值對到字典
- 29. 鍵入字典:值爲列表
- 30. 如何將多個散列值的數組中有相同鍵
這不起作用。 「blah |」,「blah」和「blah」,「| blah」這對組合如何?你需要小心。 – Keltex 2010-03-02 21:14:03