迭代时从对象列表中删除元素

我有一个id / parents列表,我正在迭代外部扩展。 这个列表可以有大约11 000行,这就是为什么我需要删除一些元素,所以我将只显示我需要的。

元素清单:

FlatData[] elements = new FlatData[] { new FlatData {Id = 3, ParentId = 1, Text = "A"}, new FlatData {Id = 4, ParentId = 1, Text = "D"}, new FlatData {Id = 5, ParentId = 2, Text = "E"}, new FlatData {Id = 7, ParentId = 2, Text = "G"}, new FlatData {Id = 8, ParentId = 4, Text = "H"}, new FlatData {Id = 9, ParentId = 8, Text = "H"}, new FlatData {Id = 10, ParentId = 8, Text = "I"}, new FlatData {Id = 11, Text = "I"}, }; 

虽然我正在迭代,我想删除一些元素,以便它们不会被处理或显示,但我要删除的元素仍然存在于输出中!

这是通过元素迭代的代码:

 int firstDepth = 0; IEnumerable  nodes = elements.Where(x => x.Id >= 4).RecursiveJoin(element => element.Id, element => element.ParentId, (FlatData element, int index, int depth, IEnumerable children) => { int position; if(depth == 0){ firstDepth++; } if(firstDepth > 0){ position= Array.FindIndex(elements, row => row.Id == index); elements.Skip(position); } return new DeepNodeData() { Id = element.Id, Index = index, Text = element.Text, }; }); 

我只知道作为根父母的起始位置(id = 4)。 一旦我有深​​度值,我只会知道要删除的元素的位置。 这个想法是只显示附加到id = 4的子元素。这里是我应该在结尾处的元素,应该处理它以构建我的树视图:

 FlatData[] elements = new FlatData[] { new FlatData {Id = 4, ParentId = 1, Text = "D" }, new FlatData {Id = 8, ParentId = 4, Text = "H" }, new FlatData {Id = 9, ParentId = 8, Text = "H" }, }; 

隐性扩展:

 public static IEnumerable RecursiveJoin(this IEnumerable source, Func parentKeySelector, Func childKeySelector, Func<TSource, int, int, IEnumerable, TResult> resultSelector) { return RecursiveJoin(source, parentKeySelector, childKeySelector, resultSelector, Comparer.Default); } public static IEnumerable RecursiveJoin(this IEnumerable source, Func parentKeySelector, Func childKeySelector, Func<TSource, int, int, IEnumerable, TResult> resultSelector, IComparer comparer) { // prevent source being enumerated more than once per RecursiveJoin call source = new LinkedList(source); // fast binary search lookup SortedDictionary parents = new SortedDictionary(comparer); SortedDictionary<TKey, LinkedList> children = new SortedDictionary<TKey, LinkedList>(comparer); foreach (TSource element in source) { parents[parentKeySelector(element)] = element; LinkedList list; TKey childKey = childKeySelector(element); if (!children.TryGetValue(childKey, out list)) { children[childKey] = list = new LinkedList(); } list.AddLast(element); } // initialize to null otherwise compiler complains at single line assignment Func<TSource, int, IEnumerable> childSelector = null; childSelector = (TSource parent, int depth) => { LinkedList innerChildren = null; if (children.TryGetValue(parentKeySelector(parent), out innerChildren)) { return innerChildren.Select((child, index) => resultSelector(child, index, depth , childSelector(child, depth + 1))); } return Enumerable.Empty(); }; return source.Where(element => !parents.ContainsKey(childKeySelector(element))) .Select((element, index) => resultSelector(element, index, 0 ,childSelector(element, 1))); }