Как мне упростить 2 foreach с помощью LINQ? - PullRequest
0 голосов
/ 08 марта 2012

Как я могу сделать это более читабельным способом?

 foreach (var actual in actualPositions)
 {
     foreach (var projection in projections)
     {
         var position        = Create(book, actual, projection);
         position.TargetNett = projection.DailyProjectedNet.ToString();
         yield return position;
     }
 }

Ответы [ 5 ]

12 голосов
/ 08 марта 2012

Вы хотите упростить это?Зачем?Это просто и читаемо и понятно.Вы можете придумать всевозможные трюки, которые труднее читать, но, конечно, выглядит круче.Не делайте!Не поддавайся желанию быть модным.

2 голосов
/ 08 марта 2012

Один из вариантов, который вы можете сделать, - реализовать собственное перекрестное соединение и перечислить его.Тем не менее, это все еще не очень красиво:

actualPositions.SelectMany(actual => projections.Select(project => new { actual, project }))

Однако, если вы используете .NET 4.0 или выше, вы можете реализовать метод расширения перекрестного соединения, используя Tuples (по умолчанию) или свой собственный селектор:

public static IEnumerable<Tuple<T1, T2>> CrossJoin<T1, T2>(this IEnumerable<T1> source, IEnumerable<T2> toJoin)
{
    return source.CrossJoin(toJoin, Tuple.Create<T1, T2>);
}

public static IEnumerable<T3> CrossJoin<T1, T2, T3>(this IEnumerable<T1> source, IEnumerable<T2> toJoin, Func<T1, T2, T3> selector)
{
    return source.SelectMany(tFirst => toJoin.Select(tSecond => selector(tFirst, tSecond)));
}

И тогда это можно использовать намного проще:

foreach(var pair in actualPositions.CrossJoin(projections))
{
    var position = Create(book, pair.Item1, pair.Item2);
    position.TargetNett = pair.Item2.DailyProjectedNet.ToString();
    yield return position;
}
// OR
return actionPositions.CrossJoin(projections, (actual, project) => { /*Code in foreach loop above here, without the "yield". */ });
2 голосов
/ 08 марта 2012
return 
  from actual in actualProjections
  from projection in projections
  select Create(book, actual, projection)
          .With_TargetNett(projection.DailyProjectedNet.ToString());

где With_TargetNett - расширение

static Position With_TargetNett(this Position position, string targetNett)
{
 position.TargetNett = targetNett;
 return position;
}
0 голосов
/ 08 марта 2012

В этом случае Linq обеспечивает меньшую читаемость.Вы можете переместить второй оператор foreach в отдельный метод, а затем использовать новый метод Linq

return from actual in actualPositions
       select GetBookPositionList(actual);

:

private List<BookPosition> GetBookPositionList(ActualPosition actual)
{
  foreach (var projection in projections)
  {
    var position = Create(book, actual, projection);
    position.TargetNett = projection.DailyProjectedNet.ToString();
    yield return position;
  }
}
0 голосов
/ 08 марта 2012

просто так

return 
 (
  from actual in actualProjections  
  from projection in projections  
  select new {actual, projection}
 ).Select(pair => 
   {
     var position = Create(book, pair.actual, pair.projection);   
     position.TargetNett = pair.projection.DailyProjectedNet.ToString();           
     return position;
   }
 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...