2010-12-14 174 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