Angular中计算JSON对象父级层级数的递归函数错误排查
Let's walk through why your code is throwing that TypeError and implement a correct solution to count the total number of recursive parents (including all ancestors) for each item in your array.
What's Causing the Error?
You're seeing Cannot read property 'parentLineIndex' of undefined for a few key reasons:
Type Mismatch in Parent Check
Your test data uses a number-1for items with no parent, but your code checks against the string'-1'. This means when an item has no parent, your conditionthis.array2[this.index2].parentLineIndex !== '-1'evaluates totrue(since-1!=='-1'), and you try to access the array at index'-1'—which doesn't exist, hence theundefinederror.Broken Recursive Count Logic
Yourcountvariable is reinitialized to1every time you call the recursive function, and you never actually add the result of the recursive call back to the current count. Even if the condition was correct, you'd never get the total number of ancestors.Unnecessary Class State Dependencies
Usingthis.index2andthis.array2to pass data between recursive calls is unnecessary and risky—it can cause state conflicts if you call the function multiple times in quick succession. Always pass values directly as function parameters instead.
Correct Implementation
First, let's clarify the requirement: we want to count all ancestor nodes (parent, grandparent, etc.) for each item—top-level items (with parentLineIndex: -1) will have a count of 0.
Option 1: Recursive Solution (Clean for Shallow Hierarchies)
This is a straightforward recursive approach with proper type checks and count accumulation:
// Calculate the total number of ancestors for a given item index calculateAncestorCount(index: number, items: any[]): number { const currentItem = items[index]; // Guard clause: if the item doesn't exist, return 0 if (!currentItem) { console.warn(`Invalid index provided: ${index}`); return 0; } // Base case: no parent, so no ancestors if (currentItem.parentLineIndex === -1) { return 0; } const parentIndex = currentItem.parentLineIndex; // Guard clause: check if parent index is valid if (parentIndex < 0 || parentIndex >= items.length) { console.warn(`Invalid parent index ${parentIndex} for item at index ${index}`); return 0; } // Recursively count parent's ancestors, plus 1 for the parent itself return 1 + this.calculateAncestorCount(parentIndex, items); } // Add the ancestor count to each item in your array processDocumentLines(lines: any[]) { return lines.map(line => ({ ...line, totalParentCount: this.calculateAncestorCount(line.lineIndex, lines) })); }
Option 2: Iterative Solution (Safer for Deep Hierarchies)
If your document lines could have extremely deep nesting, recursion might hit a stack overflow. An iterative approach avoids this:
calculateAncestorCountIterative(index: number, items: any[]): number { let count = 0; let currentIndex = index; while (true) { const currentItem = items[currentIndex]; if (!currentItem) break; // Exit loop if no parent if (currentItem.parentLineIndex === -1) break; const parentIndex = currentItem.parentLineIndex; // Guard against invalid parent indices or circular references if (parentIndex < 0 || parentIndex >= items.length || parentIndex === currentIndex) { console.warn(`Invalid parent reference for item at index ${currentIndex}`); break; } count++; currentIndex = parentIndex; } return count; }
Testing with Your Sample Data
Using your editableDocumentLines array:
- Line index 0 (AGREEMENT):
totalParentCount = 0 - Line index 1:
totalParentCount = 1(only parent is index 0) - Line index 5:
totalParentCount = 2(parent is 4, whose parent is 2) - Line index 8:
totalParentCount = 5(ancestors are 7 → 6 → 5 → 4 → 2)
How to Use It
Call processDocumentLines with your data array, and each item will have a totalParentCount property with the number of recursive parents.
内容的提问来源于stack exchange,提问作者Daniel Xav De Oliveira

