将嵌套循环转换为LINQ

时间:2018-01-31 19:21:07

标签: c# linq

我有一个属性DateTime和一个DateTimes数组。

 public DateTime date { get; set; }
 public DateTime[] dateArray { get; set; }

目前我正在使用嵌套循环来获取我的值,但我试图将其更改为LINQ并且无法使其正确。

 for (var i = 0; i < allPropertyValues.Count(); i ++)
 {
      var list = new List<DateTime>();
      for (var j = 0; j < allPropertyValues[i].dateArray.Count(); j++)
      {
           if (allPropertyValues[i].dateArray[j]
                 >= allPropertyValues[i].date)
                list.Add(allPropertyValues[i].dateArray);
      }
 }

allPropertyValues变量当前是一个静态属性数组,并且在每个索引中,有一个date值和多个dateArray值。如何使用LINQ迭代每个属性结果并将每个日期与我得到的dateArray的多个值进行比较?非常感谢提前。

另外,我如何比较两个实例,因为看起来我不能在LINQ表达式中使用><。我没有太多使用LINQ,但我正试图弄清楚它,再次感谢。

2 个答案:

答案 0 :(得分:7)

请遵循以下准则:

  • 从内到外工作
  • 将常见的子表达式提取为更简单的
  • 问问自己循环所代表的概念是什么,而不是循环所做的。然后编写一个代表该概念的查询。

行。我们有内循环,这是一个烂摊子。我已经解决了评论中提到的明显错误。

  for (var j = 0; j < allPropertyValues[i].dateArray.Count(); j++)
  {
    if (allPropertyValues[i].dateArray[j] >= allPropertyValues[i].date)
      list.Add(allPropertyValues[i].dateArray[j]);
  }

为什么一团糟?好吧,我们这里有一个共同的子表达式。简化它。

  var v = allPropertyValues[i];
  for (var j = 0; j < v.dateArray.Count(); j++)
  {
    if (v.dateArray[j] >= v.date)
      list.Add(v.dateArray[j]);
  }

这已经有一百万倍了。我们能让它变得更容易吗?是。我们有第二个共同的子表达式:

  var v = allPropertyValues[i];
  for (var j = 0; j < v.dateArray.Count(); j++)
  {
    DateTime d = v.dateArray[j];
    if (d >= v.date)
      list.Add(d);
  }

现在我们意识到j是不必要的:

  var v = allPropertyValues[i];
  foreach (DateTime d in v.dateArray)
  {
    if (d >= v.date)
      list.Add(d);
  }
OMG更容易理解。现在很清楚代码的含义是什么,因此我们可以更容易地将其转换为查询:

  var v = allPropertyValues[i];
  list.AddRange(from d in v.dateArray where d >= v.date select d);

或者

  var v = allPropertyValues[i];
  list.AddRange(v.dateArray.Where(d => d >= v.date));

现在我们已经找到了两行非常清晰的代码。

现在我们重写了内循环。把它放在外循环中:

for (var i = 0; i < allPropertyValues.Count(); i++)
{
  var list = new List<DateTime>();
  var v = allPropertyValues[i];
  list.AddRange(v.dateArray.Where(d => d >= v.date));
}

现在再次检查代码。可以简化吗?是。我们注意到列表是在必要之前创建的。

for (var i = 0; i < allPropertyValues.Count(); i++)
{
  var v = allPropertyValues[i];
  var list = v.dateArray.Where(d => d >= v.date).ToList();
}

我们可以让这个更简单吗?当然。现在我们可以注意到i是不必要的:

foreach (var v in allPropertyValues)
{
  var list = v.dateArray.Where(d => d >= v.date).ToList();
}

现在我们已经将整个事情简化为两行程序片段。

如果您想要的是列表清单,那么我们可以更进一步:

List<List<DateTime>> lists = allPropertyValues
  .Select(v => v.dateArray.Where(d => d >= v.date).ToList())
  .ToList();

我们已经完成了。

这里的要点是:不断问自己如何简化程序以使其更清晰简洁。然后应用一系列细致,小巧,正确的重构。每次你这样做,再问自己:我现在可以做得更好吗?

答案 1 :(得分:1)

尝试以下linq查询

allPropertyValues.Where(e=> e.dateArray.Any(d=>d>= e.date)).Select(e=>e.dateArray)