This is a follow up on this question which is a follow up on this question
This follow up is created, because the class in question contained something, which didn't do what it should do.
Based on the suggestion for the RemoveRootArchiveDefinitions()
method of the first follow up I have renamed the name of the return variable to remainingEntries
and renamed the method to GetNonRootArchiveDefinitions()
.
Please review the class in question, if you find anything, which should be changed.
public class ArchiveBuilder
{
public static IEnumerable<ArchiveTreeEntry> Build(IEnumerable<ArchiveDefinition> archiveDefinitions)
{
IEnumerable<ArchiveTreeEntry> rootArchiveTreeEntries = new List<ArchiveTreeEntry>();
if (archiveDefinitions != null && archiveDefinitions.Count() > 0)
{
IEnumerable<ArchiveDefinition> localEntries = new List<ArchiveDefinition>(archiveDefinitions);
rootArchiveTreeEntries = CreateRootEntries(localEntries);
localEntries = GetNonRootArchiveDefinitions(localEntries);
foreach (ArchiveTreeEntry rootEntry in rootArchiveTreeEntries)
{
HandleEntriesForParent(localEntries, rootEntry);
}
}
return rootArchiveTreeEntries;
}
private static IEnumerable<ArchiveTreeEntry> CreateRootEntries(
IEnumerable<ArchiveDefinition> archiveDefinitions)
{
List<ArchiveTreeEntry> rootArchiveTreeEntries = new List<ArchiveTreeEntry>();
rootArchiveTreeEntries.AddRange(
archiveDefinitions.Where(e => e.TypeOfArchive == ArchiveType.Archive)
.Select(d => new ArchiveTreeEntry(d)));
return rootArchiveTreeEntries;
}
private static IEnumerable<ArchiveDefinition> GetNonRootArchiveDefinitions(
IEnumerable<ArchiveDefinition> archiveDefinitions)
{
IEnumerable<ArchiveDefinition> remainingEntries =
archiveDefinitions.Except(
archiveDefinitions.Where(e => e.TypeOfArchive == ArchiveType.Archive));
return remainingEntries;
}
private static void HandleEntriesForParent(
IEnumerable<ArchiveDefinition> archiveDefinitions,
ArchiveTreeEntry parent)
{
if (archiveDefinitions.Count() > 0)
{
IEnumerable<ArchiveDefinition> children = GetChildren(archiveDefinitions, parent.Id);
AddChildrenToParent(parent, children);
archiveDefinitions = GetParentlessEntries(archiveDefinitions, parent.Id);
foreach (ArchiveTreeEntry nextParent in parent.Children)
{
HandleEntriesForParent(archiveDefinitions, nextParent);
}
}
}
private static IEnumerable<ArchiveDefinition> GetChildren(
IEnumerable<ArchiveDefinition> archiveDefinitions, string parentId)
{
return archiveDefinitions.Where(e => e.ParentId == parentId);
}
private static void AddChildrenToParent(ArchiveTreeEntry parent,
IEnumerable<ArchiveDefinition> children)
{
parent.AddChildRange(children.Select(x => new ArchiveTreeEntry(x)));
}
private static IEnumerable<ArchiveDefinition> GetParentlessEntries(
IEnumerable<ArchiveDefinition> archiveDefinitions,
string parentId)
{
return archiveDefinitions.Where(e => e.ParentId != parentId);
}
}
Regarding Any()
and Count()
as pointed out in the last follow up:
As long as the underlying object is a ICollection
or ICollection<T>
the Count()
method returns the Count
property of the underlying object. Which in turn just returns an internal counter of the items contained in the collection.
See: this question and this question
Any()
vs.Count()
: but that's the point of usingIEnumerable<T>
- you shouldn't know nor care what the underlying object is. If your logic says "the collection has any items", useAny()
. If your logic says "the collection has exactly two items", use.Count() == 2
. It's more about declarative intent than the side-benefit of optimization. \$\endgroup\$