Reputation: 34629
This is more of a language-agnostic question than a C#-specific one, but since it deals with namespaces I thought I'd tag this as .NET-related.
Say you have a bunch of strings that represent namespaces:
[
"System",
"System.Windows",
"System.Windows.Input",
"System.Windows.Converters",
"System.Windows.Markup",
"System.Windows.Markup.Primitives",
"System.IO",
"System.IO.Packaging"
]
You want to filter them in such a way that any namespace that 'contains' another namespace in the collection is excluded. For example, since System
contains System.Windows
, it's excluded. Since System.IO
is a parent of System.IO.Packaging
, it's likewise excluded. This continues until you end up with this:
[
"System.Windows.Input",
"System.Windows.Converters",
"System.Windows.Markup.Primitives",
"System.IO.Packaging"
]
What would be an efficient way to filter a list this way in C#? I'm looking for a method that will look something like this:
public IEnumerable<string> FilterNamespaces(IEnumerable<string> namespaces) {}
Any help would be appreciated, thanks!
EDIT: Here is what ultimately worked for me:
public IEnumerable<string> FilterNamespaces(IEnumerable<string> namespaces) =>
namespaces.Where(current => !namespaces.Any(n => n.StartsWith($"{current}.")));
Upvotes: 4
Views: 89
Reputation: 8318
Try following
public static IEnumerable<string> FilterNamespaces(IEnumerable<string> namespaces)
=> namespaces
.Where(ns => namespaces
.Where(n => n != ns)
.All(n => !Regex.IsMatch(n, $@"{Regex.Escape(ns)}[\.\n]")))
.Distinct();
Upvotes: 2
Reputation: 333
You can build a tree where the root is the System
namespace and every edge will represent a parent-child relation between different namespaces. Then you can find all of the leafs of the tree with a traversing algorithm which finds the rank of every node(nodes with rank=1 are leafs-they do not have children).
Upvotes: 3