0
# Array Conversion
1
2
Convert tree structures to arrays with optional filtering and custom target arrays.
3
4
## Capabilities
5
6
### Children to Array
7
8
Convert all children of a parent object to an array.
9
10
```javascript { .api }
11
/**
12
* Convert all children of parent to an array
13
* Time Complexity: O(n) where n is the number of children
14
* @param {Object} parent - Parent object
15
* @param {Object} [options] - Conversion options
16
* @param {Array} [options.array=[]] - Target array to append to
17
* @param {Function} [options.filter] - Filter function, receives (object) and should return boolean
18
* @param {*} [options.thisArg] - Value to use as 'this' when executing filter
19
* @returns {Object[]} Array of children (filtered if filter provided)
20
*/
21
childrenToArray(parent: Object, options?: {
22
array?: Object[];
23
filter?: (object: Object) => boolean;
24
thisArg?: any;
25
}): Object[];
26
```
27
28
### Ancestors to Array
29
30
Convert all inclusive ancestors of an object to an array.
31
32
```javascript { .api }
33
/**
34
* Convert all inclusive ancestors of object to an array
35
* Time Complexity: O(n) where n is the number of ancestors
36
* @param {Object} object - Starting object
37
* @param {Object} [options] - Conversion options
38
* @param {Array} [options.array=[]] - Target array to append to
39
* @param {Function} [options.filter] - Filter function, receives (object) and should return boolean
40
* @param {*} [options.thisArg] - Value to use as 'this' when executing filter
41
* @returns {Object[]} Array of ancestors including the starting object (filtered if filter provided)
42
*/
43
ancestorsToArray(object: Object, options?: {
44
array?: Object[];
45
filter?: (object: Object) => boolean;
46
thisArg?: any;
47
}): Object[];
48
```
49
50
### Tree to Array
51
52
Convert an entire tree to an array in tree order.
53
54
```javascript { .api }
55
/**
56
* Convert entire tree to an array in tree order (depth-first)
57
* Time Complexity: O(n) where n is the number of objects in the subtree
58
* @param {Object} root - Root object of the tree/subtree
59
* @param {Object} [options] - Conversion options
60
* @param {Array} [options.array=[]] - Target array to append to
61
* @param {Function} [options.filter] - Filter function, receives (object) and should return boolean
62
* @param {*} [options.thisArg] - Value to use as 'this' when executing filter
63
* @returns {Object[]} Array of tree objects in tree order (filtered if filter provided)
64
*/
65
treeToArray(root: Object, options?: {
66
array?: Object[];
67
filter?: (object: Object) => boolean;
68
thisArg?: any;
69
}): Object[];
70
```
71
72
## Usage Examples
73
74
### Basic Array Conversion
75
76
```javascript
77
const SymbolTree = require("symbol-tree");
78
const tree = new SymbolTree();
79
80
// Build a tree structure
81
const parent = { name: "parent", type: "container" };
82
const child1 = { name: "child1", type: "item" };
83
const child2 = { name: "child2", type: "item" };
84
const child3 = { name: "child3", type: "item" };
85
const grandchild = { name: "grandchild", type: "item" };
86
87
tree.appendChild(parent, child1);
88
tree.appendChild(parent, child2);
89
tree.appendChild(parent, child3);
90
tree.appendChild(child1, grandchild);
91
92
// Convert children to array
93
const children = tree.childrenToArray(parent);
94
console.log(children.map(c => c.name)); // ["child1", "child2", "child3"]
95
96
// Get all ancestors of grandchild
97
const ancestors = tree.ancestorsToArray(grandchild);
98
console.log(ancestors.map(a => a.name)); // ["grandchild", "child1", "parent"]
99
100
// Convert entire tree to array
101
const allNodes = tree.treeToArray(parent);
102
console.log(allNodes.map(n => n.name));
103
// ["parent", "child1", "grandchild", "child2", "child3"]
104
```
105
106
### Using Filters
107
108
```javascript
109
// Filter children by type
110
const itemChildren = tree.childrenToArray(parent, {
111
filter: (child) => child.type === "item"
112
});
113
console.log(itemChildren.map(c => c.name)); // ["child1", "child2", "child3"]
114
115
// Filter ancestors (exclude the starting object)
116
const actualAncestors = tree.ancestorsToArray(grandchild, {
117
filter: (obj) => obj !== grandchild
118
});
119
console.log(actualAncestors.map(a => a.name)); // ["child1", "parent"]
120
121
// Filter tree nodes by name pattern
122
const childNodes = tree.treeToArray(parent, {
123
filter: (obj) => obj.name.includes("child")
124
});
125
console.log(childNodes.map(n => n.name));
126
// ["child1", "grandchild", "child2", "child3"]
127
```
128
129
### Using Custom Arrays and Context
130
131
```javascript
132
// Append to existing array
133
const existingArray = [{ name: "external", type: "other" }];
134
const combined = tree.childrenToArray(parent, {
135
array: existingArray
136
});
137
console.log(combined.map(c => c.name));
138
// ["external", "child1", "child2", "child3"]
139
140
// Using thisArg for filter context
141
class NodeAnalyzer {
142
constructor(targetType) {
143
this.targetType = targetType;
144
}
145
146
isTargetType(obj) {
147
return obj.type === this.targetType;
148
}
149
150
getFilteredChildren(parent, tree) {
151
return tree.childrenToArray(parent, {
152
filter: this.isTargetType,
153
thisArg: this
154
});
155
}
156
}
157
158
const analyzer = new NodeAnalyzer("item");
159
const filteredChildren = analyzer.getFilteredChildren(parent, tree);
160
console.log(filteredChildren.map(c => c.name)); // ["child1", "child2", "child3"]
161
```
162
163
### Advanced Filtering Patterns
164
165
```javascript
166
// Complex filter: only nodes with specific attributes
167
const specialNodes = tree.treeToArray(parent, {
168
filter: (obj) => {
169
return obj.type === "item" &&
170
obj.name.length > 5 &&
171
tree.hasChildren(obj);
172
}
173
});
174
175
// Filter with index-like functionality (get every 2nd child)
176
let childIndex = 0;
177
const everySecondChild = tree.childrenToArray(parent, {
178
filter: () => {
179
const include = childIndex % 2 === 0;
180
childIndex++;
181
return include;
182
}
183
});
184
185
// Build hierarchy information while converting
186
const hierarchyInfo = [];
187
tree.treeToArray(parent, {
188
filter: (obj) => {
189
const depth = tree.ancestorsToArray(obj).length - 1;
190
hierarchyInfo.push({
191
node: obj,
192
depth: depth,
193
hasChildren: tree.hasChildren(obj)
194
});
195
return true; // Include all nodes
196
}
197
});
198
199
console.log(hierarchyInfo);
200
// Results in array with depth and children info for each node
201
```
202
203
### Performance Optimization Patterns
204
205
```javascript
206
// Pre-allocate array for known size (performance optimization)
207
const childCount = tree.childrenCount(parent);
208
const preallocated = new Array(childCount);
209
const children = tree.childrenToArray(parent, {
210
array: preallocated
211
});
212
213
// Batch multiple conversions
214
const results = {
215
children: [],
216
ancestors: [],
217
tree: []
218
};
219
220
// Reuse the same result object
221
tree.childrenToArray(parent, { array: results.children });
222
tree.ancestorsToArray(grandchild, { array: results.ancestors });
223
tree.treeToArray(parent, { array: results.tree });
224
```
225
226
### DOM-like Operations
227
228
```javascript
229
// Simulating DOM operations
230
function getElementsByType(root, targetType) {
231
return tree.treeToArray(root, {
232
filter: (obj) => obj.type === targetType
233
});
234
}
235
236
function getDirectChildren(parent, tagName) {
237
return tree.childrenToArray(parent, {
238
filter: (child) => child.tagName === tagName
239
});
240
}
241
242
function getAncestorsByClass(node, className) {
243
return tree.ancestorsToArray(node, {
244
filter: (ancestor) => {
245
return ancestor !== node &&
246
ancestor.className &&
247
ancestor.className.includes(className);
248
}
249
});
250
}
251
252
// Usage
253
const divs = getElementsByType(parent, "div");
254
const buttons = getDirectChildren(parent, "button");
255
const containers = getAncestorsByClass(grandchild, "container");
256
```
257
258
### Functional Programming Patterns
259
260
```javascript
261
// Chain array operations after conversion
262
const processedChildren = tree.childrenToArray(parent)
263
.filter(child => child.type === "item")
264
.map(child => ({ ...child, processed: true }))
265
.sort((a, b) => a.name.localeCompare(b.name));
266
267
// Reduce tree to summary
268
const treeSummary = tree.treeToArray(parent)
269
.reduce((summary, node) => {
270
summary.totalNodes++;
271
summary.byType[node.type] = (summary.byType[node.type] || 0) + 1;
272
if (tree.hasChildren(node)) {
273
summary.containers++;
274
}
275
return summary;
276
}, { totalNodes: 0, containers: 0, byType: {} });
277
278
console.log(treeSummary);
279
// { totalNodes: 5, containers: 2, byType: { container: 1, item: 4 } }
280
```