What is the best way to find all addicted children in the IEnumerable collection

I have a database with two tables:

  • Items
  • ItemDependencies

Items have an ID key

ItemDependencies have two columns: ItemId and DependsOnItemId

I will convert this to a collection:

 IEnumerable<Item> items = GetItems();

each element has a Dependency property , which is

List<Item>

So, I want to filter out the list of initial elements:

  • Given a single element, I want the list of this element and all elements that depend on this element to be recursive.

  • Given one element, I need a list of this element and all the other elements on which it depends (also recursively).

What is the best way to do this in C #, LINQ, or anything else that could do the trick.

+3
2

, :

IEnumerable<Item> GetAllDependencies(Item i)
{
    IEnumerable<Item> a = new Item[] { i };
    IEnumerable<Item> b = i.Dependencies
                           .SelectMany(d => GetAllDependencies(d))
                           .Distinct();
    return a.Concat(b);
}

, ( , , StackOverflowException).

, , .

+5

.

public IEnumerable<Item> GetAllDependencies(Item search)
{
    return PrivateGetAllDependencies(search, new HashSet<Item>());
}

private IEnumerable<Item> PrivateGetAllDependencies(Item search, HashSet<Item> visited)
{
    if (!visited.Contains(search))
    {
        visited.Add(search);
        foreach (Item child in search.Dependencies)
        {
            PrivateGetAllDependencies(child, visited);
        }
    }
    return visited;
}

.

public IEnumerable<Item> GetAllBackReferences(Item search)
{
    return PrivateGetAllBackReferences(search, search, new HashSet<Item>(), new HashSet<Item>());
}

private IEnumerable<Item> PrivateGetAllBackReferences(Item search, Item target, HashSet<Item> visited, HashSet<Item> matched)
{
    if (!visited.Contains(search))
    {
        visited.Add(search);
        if (search == target)
        {
            matched.Add(search);
        }
        foreach (Item child in search.Dependencies)
        {
            PrivateGetAllBackReferences(child, target, visited, matched);
            if (child == target)
            {
                if (!matched.Contains(search))
                {
                    matched.Add(search);
                }
            }
        }
    }
    return matched;
}

.

0

Source: https://habr.com/ru/post/1755130/


All Articles