tags:

views:

150

answers:

3

I have a string which denotes a filter path (eg. "Plant Filters\Equipment\Equipment List") The leaf node is of type Filter and rest are FilterFolders.

I need to:

  1. Go thru each node (not leaf) and get it's -> Folders
  2. Check the next entry in the path and see if it matches a folder from above
  3. If it matches, it's the last-1, then it gets its Filters
  4. Then check its Filters and see if it matches the last string entry, if not, then get its folder and basically go back to step 2.

What's the best way to do this?

A: 

well, i am little confused with no sample code, but as far as i know anything can be linqed, if it is collection, Classes,etc... what i suggest to do is to create a string array of that path with split function, then query that string, use Switch operator or If else.

i really need to see sample so i can judge more precisely.

hope this helps.

+1  A: 

This is a recursive structure and cannot be handled with the LINQ standard query operators. Here you can find an implementation of the Y-combinator that allows to write recursive lambda expression. I am not sure if you should use it because under the hood it is quite a complex solution to a simple problem. This implementation of a recursive query operator (Note that the linked blog entry is not the correct final solution - read the later entries to get it right) is much simpler but does not solve the general problem of defining recursive lambda expressions.

Daniel Brückner
A: 

I tried this way after defining a ForEachIndex extn. Have not tested it (duhh), should work I think.

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;
    }
Sunit