C # - лямбда против вложенных циклов - PullRequest
2 голосов
/ 14 декабря 2010

Можно ли преобразовать следующее в более простое и удобочитаемое выражение 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 - это массив (int []) TierID, в котором в данный момент находится клиент.Также объект doc содержит объект CommitmentProgram, который содержит список PriceProgram.Итак, все, что я пытаюсь сделать, это получить PriceProgram.ProgramID для каждого TierID.

Связь между PriceProgram и TierID заключается в том, что каждая PriceProgram имеет список уровней (объект ProgramTier), а объект ProgramTier содержит соответствующий TierID, который у нас уже есть.

Дайте мне знать, если мое объяснение нене имеет смысла, и я попытаюсь уточнить.

Редактировать

Джон, я получаю Название 'priceProgram' не существует в текущемcontext ошибка, когда я пытаюсь скомпилировать то, что вы предложили:

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 ]

4 голосов
/ 14 декабря 2010

Безусловно, это очень просто - но мне придется изменить тип вашей переменной 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, и вы не используете его отдельно от этого ...

2 голосов
/ 14 декабря 2010

Ответ Джона - правильная идея, для компиляции ее просто нужно переставить.Вот два варианта.

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);
1 голос
/ 14 декабря 2010

Единственный вид меня раздражает, но я должен согласиться с тем, о чем просят.

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);
...