2009-04-14 66 views
0

我有一个表示过滤器路径的字符串(例如“Plant Filters \ Equipment \ Equipment List”) 叶节点的类型为Filter,其余为FilterFolders。这是LINQable吗?

我需要:

  1. 转到直通每个节点(非叶),并得到它 - >文件夹
  2. 检查路径中的下一个条目,看看它是否从上面
  3. 文件夹匹配如果匹配,这是最后-1,那么它得到它的过滤器
  4. 然后检查其过滤器,看看它是否最后一个字符串项匹配,如果没有,那么得到的文件夹,基本回到步骤2

这样做的最好方法是什么?

+0

如果不是Linq的代码示例,我们将看看我们是否可以使用Linq或lambdas来做到这一点? – 2009-04-14 15:48:54

回答

0

好吧,我有点困惑,没有示例代码, 但据我所知任何东西都可以linqed,如果它是集合,类等... 我建议做的是创建一个字符串数组用split函数分析该路径,然后查询该字符串,使用Switch运算符或If else。

我真的需要看样品,所以我可以更准确地判断。

希望这有助于。

1

这是一个递归结构,不能用LINQ标准查询操作符处理。在这里你可以找到允许写递归lambda表达式的implementation of the Y-combinator。我不确定你是否应该使用它,因为在一个简单的问题下,这是一个相当复杂的解决方案。这个implementation of a recursive query operator(请注意,链接的博客条目不是正确的最终解决方案 - 阅读后面的条目以使其正确)简单得多,但不能解决定义递归lambda表达式的一般问题。

0

我在定义一个ForEachIndex extn后试过这种方法。没有测试过(duhh),我应该工作。

public static FilterBase FilterFromPath(this Site activeSite, string filterPath) 
    { 
     //"Catalog Filters\Default Filters\SP3D Report Filters\Types of Reports\Equipment\Equipment Material Take-Off"    
     Checks.IsNotNull(() => activeSite.ActivePlant); 

     FilterFolder currentFolder = null; 
     string plantFilters = CmnLocalizer.GetString(CmnResourceIDs.CmnFilterPlantFiltersFolder, "Plant Filters"); 
     string catalogFilters = CmnLocalizer.GetString(CmnResourceIDs.CmnFilterCatalogFiltersFolder, "Catalog Filters"); 

     if (filterPath.StartsWith(plantFilters)) 
      currentFolder = activeSite.ActivePlant.PlantModel.Folders[0] as FilterFolder; 
     else if (filterPath.StartsWith(catalogFilters)) 
      currentFolder = activeSite.ActivePlant.PlantCatalog.Folders[0] as FilterFolder; 
     else 
      throw new ArgumentException("Invalid filter root specified. Should start with Plant or Catalog Filters"); 

     IEnumerable<string> pathEntries = filterPath.Split(new string[] { @"\" }, StringSplitOptions.RemoveEmptyEntries).Skip(1); 
     Checks.IsNotNull(() => pathEntries); 
     if (pathEntries.Count() == 0) 
      throw new ArgumentException("Invalid filter path specified"); 

     int lastIndex = pathEntries.Count() - 1;    
     FilterBase filterFound = null; 

     pathEntries.ForEachIndex((item, index) => 
     { 
      if (index == lastIndex) 
      { 
       filterFound = currentFolder.ChildFilters.FirstOrDefault(f => f.Name.Equals(item)); 
       if (filterFound.Equals(default(FilterBase))) 
        throw new ArgumentException(string.Format("Filter '{0}' could not be found", item)); 
      } 
      else 
      { 
       currentFolder = currentFolder.ChildFolders.FirstOrDefault(f => f.Name.Equals(item)); 
       if (currentFolder.Equals(default(FilterFolder))) 
        throw new ArgumentException(string.Format("Folder '{0}' given in filter path not found", item)); 
      } 
     }); 

     return filterFound; 
    }