C# - Lambda vs嵌套循环

时间:2010-12-14 17:43:23

标签: c# linq loops lambda nested-loops

是否可以将以下内容转换为更简单易读的linq或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对象包含我们已经拥有的相应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);

3 个答案:

答案 0 :(得分: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.TierIDmainTierID相同,而你却没有使用它除此之外......

答案 1 :(得分: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);

答案 2 :(得分: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);