【问题标题】:Refactor nested loops into a single LINQ Query将嵌套循环重构为单个 LINQ 查询
【发布时间】:2012-11-20 13:21:08
【问题描述】:

我正在尝试将其重构为查询:

 while (IsRunning)
 {

 ...

 //specialPoint is a string
 foreach (PointTypeItem pointTypeItem in PointTypeItemCollection)
    {
        foreach (PointItem pointItem in pointTypeItem.PointItemCollection)
        {
            //Replace the point name with point ID
            if (specialPoint.Contains(pointItem.PointName))
            {
                replacedCode += s.Replace(specialPoint , pointItem.ID);
                //I want to go back to the beginning point of while (IsRunning) from here
                //Simply putting continue; here won't work
            }
        }
    }
 }

我基本上想把它变成一个 LINQ 查询,但我一直在写一个。实际上,我什至不确定我是否采取了正确的方向。

var results = from pointTypeItem in ddcItem.PointTypeItemCollection
              where pointTypeItem.PointItemCollection.Any(pointItem => pointName.Contains(pointItem.PointName))
              select //What do I select?

【问题讨论】:

  • 反正你还是会遍历每一项,那么这次重构的目的是什么?
  • s 是什么,replacedCode 是什么?你能提供一个简单的例子和​​期望的结果吗?

标签: c# .net linq


【解决方案1】:
var results = from pointTypeItem in ddcItem.PointTypeItemCollection
              from pointItem in pointTypeItem.PointItemCollection
              where specialPoint.Contains(pointItem.PointName)
              select pointItem.ID;

获得IEnumerable&lt;<i>the type of pointItem.ID</i>&gt;

【讨论】:

  • 病了,我从来不知道你可以在里面嵌套 from 子句!谢谢。很有见地
  • @l46kok 这实际上不是嵌套查询。它将被转换为对SelectMany 的一次调用,而不是为每个查询执行一次查询。
  • @Richard 根据 OP 代码中的 cmets,他需要在查询结束时调用 First
  • @Servy 也许,if 的内容就目前而言没有意义:不清楚s 是什么。 cmets 会建议在 specialPoint (specialPoint.Replace(pointItem, pointItem.ID)) 中进行替换,但随后将不需要 if(如果名称不存在,则替换将是无操作的)。
【解决方案2】:

您可以使用 SelectMany() 扩展方法来做到这一点:

 PointTypeItemCollection.SelectMany(pointCollection => pointCollection.PointItemCollection)
                .Where(pointItem => pointItem.PointName.Contains(specialPoint))
                .Select(pointItem => pointItem.ID);

【讨论】:

    【解决方案3】:

    在没有任何值的情况下很难进行测试,但是像这样的东西呢?

          replacedCode = string.Concat(
            this.PointTypeItemCollection.SelectMany(i => i.PointItemCollection)
            .Where(i => specialPoint.Contains(i.PointName))
            .Select(i => s.Replace(specialPoint, i.ID))
          );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      • 2020-12-07
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      相关资源
      最近更新 更多