2009-09-10 49 views

回答

172

這是一個IGrouping和字典之間的交叉。它可以讓你通過一個鍵將項目分組在一起,但是通過這個鍵以高效的方式訪問它們(而不是僅僅遍歷它們,這是GroupBy可以讓你做的)。

例如,你可以採取.NET類型的負載,並建立由命名空間查找......然後得到在特定的命名空間的所有類型很容易:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml; 

public class Test 
{ 
    static void Main() 
    { 
     // Just types covering some different assemblies 
     Type[] sampleTypes = new[] { typeof(List<>), typeof(string), 
            typeof(Enumerable), typeof(XmlReader) }; 

     // All the types in those assemblies 
     IEnumerable<Type> allTypes = sampleTypes.Select(t => t.Assembly) 
               .SelectMany(a => a.GetTypes()); 

     // Grouped by namespace, but indexable 
     ILookup<string, Type> lookup = allTypes.ToLookup(t => t.Namespace); 

     foreach (Type type in lookup["System"]) 
     { 
      Console.WriteLine("{0}: {1}", 
           type.FullName, type.Assembly.GetName().Name); 
     } 
    } 
} 

(我通常。使用var大多數這些聲明的,在正常的代碼)

+43

我覺得做這個答案更好,你可以代替某些瓦爾的。爲了學習的目的,我認爲當類型明確表達時,更容易遵循。只是我的2美分:) – 2009-09-16 03:42:02

+3

如果它具有兩個世界的最佳,那麼爲什麼要打擾字典? – 2013-03-21 02:30:20

+12

@KyleBaran:因爲對於真正的鍵/值對集合,每個鍵只有一個值是沒有意義的。 – 2013-03-21 06:41:45

11

我還沒有成功地使用過它,但這裏是我去:

一個Lookup<TKey, TElement>會表現得非常像(關係型)數據庫的索引一個沒有獨特的表格e約束。在相同的地方使用它,你會使用其他的地方。

51

想一想的一種方法是:Lookup<TKey, TElement>Dictionary<TKey, Collection<TElement>>類似。基本上可以通過同一個鍵返回零個或多個元素的列表。

namespace LookupSample 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<string> names = new List<string>(); 
      names.Add("Smith"); 
      names.Add("Stevenson"); 
      names.Add("Jones"); 

      ILookup<char, string> namesByInitial = names.ToLookup((n) => n[0]); 

      // count the names 
      Console.WriteLine("J's: {0}", namesByInitial['J'].Count()); 
      Console.WriteLine("S's: {0}", namesByInitial['S'].Count()); 
      Console.WriteLine("Z's: {0}", namesByInitial['Z'].Count()); 
     } 
    } 
} 
+2

查找結果中可以有零個元素嗎?你會怎麼做到的? (據我所知,查找是公開的不可變的,我認爲ToLookup不會有效地發明密鑰。) – 2009-09-10 05:32:14

+8

從技術上講,是的,因爲Lookup爲不存在的鍵返回空集合(我編輯了我的帖子以添加顯示這個的代碼示例)。 – bobbymcr 2009-09-10 05:49:12

5

我想你可以這樣爭論:想象你正在創建一個數據結構來保存電話簿的內容。你想按lastName鍵,然後按firstName鍵。在這裏使用字典會很危險,因爲很多人可以擁有相同的名字。因此,一本詞典至多會映射到一個單一的值。

查找將映射到可能的幾個值。

查詢[「史密斯」] [「約翰」]將是一個大小10億的集合。

+0

您的回答激發了我的後續問題[「HowLoopup()與多個索引?」](http://stackoverflow.com/questions/15734454/how-tolookup-with-multiple-indexes)。我怎麼能重現這樣的,與多個索引,查找?你可以使用任何其他樣本或引用來回答嗎?在哪裏可以使用'Lookup [「Smith」] [「John」]'? – Fulproof 2013-04-01 03:27:50

17

Lookup的一種用法可能是顛倒Dictionary

假設您的電話簿實現爲Dictionary,並且有一些(唯一)名稱作爲鍵,每個名稱都與電話號碼關聯。但是名稱不同的兩個人可能共享相同的電話號碼。這對Dictionary不是問題,它不關心兩個鍵對應相同的值。

現在,您需要一種查找給定電話號碼所屬的人的方式。您構建Lookup,將Dictionary中的所有KeyValuePairs添加到其中,但向後添加的值爲鍵和鍵爲值。您現在可以查詢電話號碼,並獲取所有電話號碼爲的人員的名單。(或失敗取決於你是如何做到的)大樓內,以相同的數據Dictionary會丟棄數據,因爲這樣做

dictionary["555-6593"] = "Dr. Emmett Brown"; 
dictionary["555-6593"] = "Marty McFly"; 

意味着第二項覆蓋第 - 的文檔不再一一列出。

試圖在一個稍微不同的方式來寫相同的數據:

dictionary.Add("555-6593", "Dr. Emmett Brown"); 
dictionary.Add("555-6593", "Marty McFly"); 

會拋出一個異常,在第二行,因爲你不能Add關鍵是已經在Dictionary

[當然,您可能希望使用其他單一數據結構在兩個方向上執行查找等。此示例意味着每次後者更改時都必須從Dictionary重新生成Lookup。但對於一些數據可能是正確的解決方案。]

相關問題