2010-12-14 241 views
2

可以將下列內容轉換爲更簡單的可讀性更強的linq或lambda表達式嗎?C# - lambda與嵌套循環

Dictionary<int, int> selectedProgramTierCombo = new Dictionary<int,int>(); 
foreach (int mainTierID in doc.TierID) 
{ 
    foreach (PriceProgram priceProgram in doc.CommitmentProgram.PricingPrograms) 
    { 
     foreach (ProgramTier progTier in priceProgram.Tiers) 
     { 
      if (progTier.TierID == mainTierID) 
      { 
       selectedProgramTierCombo.Add(priceProgram.ProgramID, progTier.TierID); 
      } 
     } 
    } 
} 

本質上doc.TierID是客戶端當前所在的TierID的一個數組(int [])。 doc對象還包含一個CommitmentProgram對象,其中包含一個PriceProgram列表。所以,我試圖做的是獲取每個TierID的PriceProgram.ProgramID。

PriceProgram和TierID之間的關係是每個PriceProgram都有一個層次列表(ProgramTier對象),而ProgramTier oject包含我們已經擁有的對應TierID。

讓我知道如果我的解釋沒有意義,我會盡力詳細說明。

編輯

喬恩, 我得到「priceProgram」這個名字時,我嘗試編譯您建議什麼並不在當前的背景下存在錯誤:

Dictionary<int, int> selectedProgramTierCombo = 
    (from mainTierID in doc.TierID 
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    **join progTier in priceProgram.Tiers on mainTierID equals progTier.TierID** 
    select new { priceProgram.ProgramID, progTier.TierID }) 
    .ToDictionary(x => x.ProgramID, x => x.TierID); 
+0

使用泛型類型 'System.Collections.Generic.List ' 要求 '1' 類型的參數。 – ja72 2010-12-14 17:54:55

+0

我已經根據Jon的初步答案提供了更新的代碼。 – 2010-12-14 19:11:51

+0

我已經編輯了我的答案,使用另一個'from'子句而不是'join' ...雖然聽起來你根本不需要那麼一點,真的。 – 2010-12-14 19:41:50

回答

4

絕對,這很容易 - 但我不得不改變你的selectedProgramTierCombo變量的類型,否則它將不能編譯:

編輯:哎呀,鑑於層級取決於priceProgram,你需要另外一個嵌套from條款,我認爲:

Dictionary<int, int> selectedProgramTierCombo = 
    (from mainTierID in doc.TierID 
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    from progTier in priceProgram.Tiers 
    where mainTierID == progTier.TierID 
    select new { priceProgram.ProgramID, progTier.TierID }) 
    .ToDictionary(x => x.ProgramID, x => x.TierID); 

至少,這就是我想你想。如果你能澄清你真正想要的而不是List<int, int>(這是無效的),我們可以進一步提供幫助。

說實話,這是我不明白你爲什麼使用progTier在所有 - 你知道progTier.TierID相同mainTierID,和你不使用它除了那個......

+0

也許他的意思是(或者需要)'List >',假設'x.ProgramID'不是用於這個集合的唯一標識符?然而,它不會大大改變答案。 – 2010-12-14 17:53:19

+0

@Anthony:可能。這很難說:( – 2010-12-14 17:53:56

+0

我在考慮在你的評論之前通過連接來處理這個問題。有人提到我從未使用過的SelectMany(),這不是一個可行的解決方案嗎?另外,我通常不會爲鑄造而煩惱,只是將整個東西打成瓦,特別是如果結構永遠不會離開功能塊。這純粹是一種風格問題,但對海報可能有用。 – Sprague 2010-12-14 17:58:58

2

Jon的答案是正確的想法,只需要重新排列以便編譯。這裏有兩個選項。

var dict = (from mainTierID in doc.TierID 
      join f in 
       (from priceProgram in doc.CommitmentProgram.PricingPrograms 
        from progTier in priceProgram.Tiers 
        select new { priceProgram.ProgramID, progTier.TierID }) 
       on mainTierID equals f.TierID 
      select f).ToDictionary(f => f.ProgramID, f => f.TierID); 


var dict2 = (from priceProgram in doc.CommitmentProgram.PricingPrograms 
       from progTier in priceProgram.Tiers 
       join mainTierID in doc.TierID on progTier.TierID equals mainTierID 
       select new { priceProgram.ProgramID, progTier.TierID }) 
      .ToDictionary(x => x.ProgramID, x => x.TierID); 
+0

謝謝安東尼。第一個變體真的有助於澄清代碼中發生了什麼=) – Robert 2010-12-14 21:40:35

1

單一類的錯誤我,但我必須去與什麼被要求。

Dictionary<int, int> selectedProgramTierCombo = 
(
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    let tierId = 
    (
    from progTier in priceProgram.Tiers 
    where doc.TierID.Any(mainTierID => mainTierID == progTier.TierID) 
    select progTier.TierID 
).Single() 
    select new 
    { 
    ProgramID = priceProgram.ProgramID, 
    TierID = tierID 
    } 
).ToDictionary(x => x.ProgramID, x => x.TierID); 

這是我會更舒服:

ILookup<int, int> selectedProgramTierCombo = 
(
    from priceProgram in doc.CommitmentProgram.PricingPrograms 
    from progTier in priceProgram.Tiers 
    where doc.TierID.Any(mainTierID => mainTierID == progTier.TierID) 
    select new 
    { 
    ProgramID = priceProgram.ProgramID, 
    TierID = progTier.TierID 
    } 
).ToLookup(x => x.ProgramID, x => x.TierID); 
+0

謝謝大衛。是否有一個特定的原因,你爲什麼使用ILookup而不是Dictionary?如果是這樣,我想知道爲什麼。 – Robert 2010-12-14 21:31:56

+0

由於doc.TierID中可能有多個項目,並且priceProgram.Tiers中可能有多個匹配的層次...給定的定價程序可能有多個主層(至少在技術層面上)。 ILookup允許我爲一個密鑰提供多個值。 – 2010-12-15 15:26:49

+0

有道理。謝謝! – Robert 2010-12-15 23:39:25