0
        List<Categories> categories = new List<Categories>
        {
            new Categories { CatID = 1, CatName = "Computer, IT & Networking"},
            new Categories { CatID = 2, CatName = "Computer & Servers"},
            new Categories { CatID = 3, CatName = "Desktop PCs"},
            new Categories { CatID = 4, CatName = "Servers"},
            new Categories { CatID = 5, CatName = "Computer Parts & Components"},
            new Categories { CatID = 6, CatName = "Harddrive"},
            new Categories { CatID = 7, CatName = "CPUs"},
            new Categories { CatID = 8, CatName = "Electronics"},
            new Categories { CatID = 9, CatName = "Furniture"},
            new Categories { CatID = 10, CatName = "RAM"},
            new Categories { CatID = 11, CatName = "Harddrive"},
            new Categories { CatID = 12, CatName = "Workbooks"},
            new Categories { CatID = 13, CatName = "IBM Desktop"},
            new Categories { CatID = 14, CatName = "HP Desktop"}
        };

        List<CategoriesMapping> categoriesMapping = new List<CategoriesMapping>
        {
            new CategoriesMapping { CategoriesMappingID = 1, CatID = 1, MapCatID = 2},
            new CategoriesMapping { CategoriesMappingID = 2, CatID = 1, MapCatID = 5},
            new CategoriesMapping { CategoriesMappingID = 3, CatID = 2, MapCatID = 3},
            new CategoriesMapping { CategoriesMappingID = 4, CatID = 2, MapCatID = 4},
            new CategoriesMapping { CategoriesMappingID = 5, CatID = 5, MapCatID = 6},
            new CategoriesMapping { CategoriesMappingID = 6, CatID = 5, MapCatID = 7},
            new CategoriesMapping { CategoriesMappingID = 7, CatID = 5, MapCatID = 10},
            new CategoriesMapping { CategoriesMappingID = 8, CatID = 5, MapCatID = 11},
            new CategoriesMapping { CategoriesMappingID = 9, CatID = 2, MapCatID = 12},
            new CategoriesMapping { CategoriesMappingID = 10, CatID = 3, MapCatID = 13},
            new CategoriesMapping { CategoriesMappingID = 11, CatID = 3, MapCatID = 14}
        };

How can i get the last nodes of a specific CatID for example on the above code, if i choose CatID = 2 it should only bring back CatIDs 4,12,13,14. It should not return its sub-category CatID 3 because it also has nodes within which are 13 & 14. Rather it return the child-nodes of CatID 3 only.

zvikow
  • 21
  • 2

3 Answers3

2

I'm assuming that you are trying to solve this using linq magic. Unfortunately, in this answer by Jon Skeet, you can see that it is quite incovenient.

You can try something like this, but it can get quite expensive.

My suggestion would be to create a new function like

   public List<int> GetNoDescendateCategoriesCategoryId(int categoryId) {
       List<int> newCategories = new List<int>();
       List<int> childCategories = this.categoriesMapping.Where(m => m.CatID == categoryId).Select(x=> x.MapCatID).ToList();

       if(childCategories.Count == 0) {
          return new List<int>() {categoryId};
       }
       foreach (int catId in childCategories ) {
          newCategories.AddRange(GetNoDescendateCategoriesCategoryId(catId));
       }
       return newCategories;
   }

You can check the https://dotnetfiddle.net/1IbjOf for this as an example.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
0

As this is a recursive call, I don't think that LINQ is the best way to do it. Having a simple iterative or recursive function does the job.


    public IEnumerable<int> ExtractSubcategories(int categoryId)
    {
        var categories = new List<int> {categoryId};
        var subCategories = new List<int>();

        while (categories.Count > 0)
        {
            // categories will store the categories to check
            int cat = categories[0];
            categories.RemoveAt(0);

            // checking the mapped categories
            var mapped = categoriesMapping.Where(x => x.CatID == cat)
                                          .Select(x => x.MapCatID)
                                          .ToList();
            if (mapped.Count > 0) 
            {
                // there are mapped categories,
                // thus we look for their children
                categories.AddRange(mapped);
            }
            else 
            {
                // there are no mapped categories,
                // this category is a child, we add it to the result
                subCategories.Add(cat);
            }
        }

        return subCategories;
    }


    [Test]
    public void Test() => 
        CollectionAssert.AreEquivalent(ExtractSubcategories(2), new[] {4, 12, 13, 14});

Alvin Sartor
  • 2,249
  • 4
  • 20
  • 36
0

You can try the following,

public class A {

    public List<int> result = new List<int>();

    public static List<CategoriesMapping> categoriesMapping = new List<CategoriesMapping> {
        //your data
    };

    public List<int> GetChildren(int input) {
        var res = GetInnerChildren(input);
        if (res.Count == 0)
            result.Add(input);

        foreach (var item in res) {
            if (categoriesMapping.Count(x => x.CatID == item) == 0) {
                result.Add(item);
            }
            else {
                var childs = GetInnerChildren(item);
                foreach (var item2 in childs) {
                    GetChildren(item2);
                }
            }
        }
        result.Sort();
        return result;
    }

    public List<int> GetInnerChildren(int input) {
        return categoriesMapping.Where(x => x.CatID == input).Select(x => x.MapCatID).ToList() ?? new List<int>();
    }

}

Your CategoriesMapping model,

public class CategoriesMapping {
    public int CategoriesMappingID { get; set; }
    public int CatID { get; set; }
    public int MapCatID { get; set; }
}

GetChildren returns the desired output as you want

GetChildren(2) => returns 4,12,13,14

Furkan Öztürk
  • 1,178
  • 11
  • 24