2009-03-06 30 views
4

這很常見 - 特別是當你試圖讓你的代碼變得更多的數據驅動 - 需要迭代關聯的集合。例如,我剛寫完一段代碼,看起來像這樣:用於迭代相關聯的值集合的模式是什麼?

string[] entTypes = {"DOC", "CON", "BAL"}; 
string[] dateFields = {"DocDate", "ConUserDate", "BalDate"}; 
Debug.Assert(entTypes.Length == dateFields.Length); 

for (int i=0; i<entTypes.Length; i++) 
{ 
    string entType = entTypes[i]; 
    string dateField = dateFields[i]; 
    // do stuff with the associated entType and dateField 
} 

在Python中,我會寫這樣的:

items = [("DOC", "DocDate"), ("CON", "ConUserDate"), ("BAL", "BalDate")] 
for (entType, dateField) in items: 
    # do stuff with the associated entType and dateField 

我不需要申報並行陣列,我不需要斷言我的數組長度相同,我不需要使用索引來獲取項目。

我覺得有使用LINQ在C#這樣做的方式,但我想不出它可能是什麼。是否有一些簡單的迭代方法可以跨多個關聯的集合?

編輯:

這是一個好一點,我覺得 - 至少,在情況下我必須在報關手動荏苒收藏的奢侈品,並在所有集合包含相同的對象類型:

List<string[]> items = new List<string[]> 
{ 
    new [] {"DOC", "DocDate"}, 
    new [] {"CON", "ConUserDate"}, 
    new [] {"SCH", "SchDate"} 
}; 
foreach (string[] item in items) 
{ 
    Debug.Assert(item.Length == 2); 
    string entType = item[0]; 
    string dateField = item[1]; 
    // do stuff with the associated entType and dateField 
} 
+0

一個爲什麼需要「更多的壓縮,但不易閱讀」的方式來寫東西,而不是定義的結構還是一個類? – Hamid 2009-03-15 21:58:28

+0

如果您有30或40對值,則必須編寫相同的成員名稱30次或40次,這不會使代碼*更具可讀性。 – 2009-03-16 02:17:07

回答

3

在.NET 4.0中他們增加一個 「拉鍊」 擴展方法的IEnumerable,所以你的代碼可能看起來是這樣的:

foreach (var item in entTypes.Zip(dateFields, 
    (entType, dateField) => new { entType, dateField })) 
{ 
    // do stuff with item.entType and item.dateField 
} 

現在我認爲最簡單的事情就是把它作爲for循環。有一些技巧可以引用「其他」數組(例如,通過使用提供索引的Select()的重載),但它們都不像簡單的迭代器那麼幹淨。

Here's a blog post about Zip as well as a way to implement it yourself。應該讓你在此期間去。

+0

很好,期待它 – johnc 2009-03-06 01:52:33

2

創建一個結構?

struct Item 
{ 
    string entityType; 
    string dateField; 
} 

與您的Pythonic解決方案几乎相同,除了類型安全。

0

您可以使用該對和一個通用列表。

List<Pair> list = new List<Pair>(); 

list.Add(new Pair("DOC", "DocDate")); 
list.Add(new Pair("CON", "ConUserDate")); 
list.Add(new Pair("BAL", "BalDate")); 

foreach (var item in list) 
{ 
    string entType = item.First as string; 
    string dateField = item.Second as string; 

    // DO STUFF 
} 

Pair是Web.UI的一部分,但您可以輕鬆創建自己的自定義類或結構。

+0

雖然這不比我現在寫的代碼少,事實上,它更多。如果我有兩個以上的關聯列表,它也會崩潰。 – 2009-03-06 19:01:49

0

如果你只是想在線申報清單,你可以做到一步到位:

var entities = new Dictionary<string, string>() { 
    { "DOC", "DocDate" }, 
    { "CON", "ConUserDate" }, 
    { "BAL", "BalDate" }, 
}; 
foreach (var kvp in entities) { 
    // do stuff with kvp.Key and kvp.Value 
} 

如果他們從其他的東西來了,我們有一大堆的擴展方法來構建各種字典數據結構。

+0

有兩個問題:1)它不能處理兩個以上的關聯列表; 2)字典在迭代鍵時強加自己的順序。但看到我的編輯。 – 2009-03-06 19:14:36

1

這是真的對其他主題的變化,但這會做的伎倆也...

var items = new[] 
      { 
       new { entType = "DOC", dataField = "DocDate" }, 
       new { entType = "CON", dataField = "ConUserData" }, 
       new { entType = "BAL", dataField = "BalDate" } 
      }; 

foreach (var item in items) 
{ 
    // do stuff with your items 
    Console.WriteLine("entType: {0}, dataField {1}", item.entType, item.dataField); 
} 
相關問題