| 241 | }, |
| 242 | ): BinarySearchTree<U>; |
| 243 | static from<T, U, V>( |
| 244 | collection: ArrayLike<T> | Iterable<T> | BinarySearchTree<T>, |
| 245 | options?: { |
| 246 | compare?: (a: U, b: U) => number; |
| 247 | map?: (value: T, index: number) => U; |
| 248 | thisArg?: V; |
| 249 | }, |
| 250 | ): BinarySearchTree<U> { |
| 251 | let result: BinarySearchTree<U>; |
| 252 | let unmappedValues: ArrayLike<T> | Iterable<T> = []; |
| 253 | if (collection instanceof BinarySearchTree) { |
| 254 | result = new BinarySearchTree( |
| 255 | options?.compare ?? |
| 256 | (collection as unknown as BinarySearchTree<U>).#compare, |
| 257 | ); |
| 258 | if (options?.compare || options?.map) { |
| 259 | unmappedValues = collection; |
| 260 | } else { |
| 261 | const nodes: BinarySearchNode<U>[] = []; |
| 262 | if (collection.#root) { |
| 263 | result.#root = BinarySearchNode.from( |
| 264 | collection.#root as unknown as BinarySearchNode<U>, |
| 265 | ); |
| 266 | nodes.push(result.#root); |
| 267 | } |
| 268 | while (nodes.length) { |
| 269 | const node: BinarySearchNode<U> = nodes.pop()!; |
| 270 | const left: BinarySearchNode<U> | null = node.left |
| 271 | ? BinarySearchNode.from(node.left) |
| 272 | : null; |
| 273 | const right: BinarySearchNode<U> | null = node.right |
| 274 | ? BinarySearchNode.from(node.right) |
| 275 | : null; |
| 276 | |
| 277 | if (left) { |
| 278 | left.parent = node; |
| 279 | nodes.push(left); |
| 280 | } |
| 281 | if (right) { |
| 282 | right.parent = node; |
| 283 | nodes.push(right); |
| 284 | } |
| 285 | } |
| 286 | result.#size = collection.#size; |
| 287 | } |
| 288 | } else { |
| 289 | result = (options?.compare |
| 290 | ? new BinarySearchTree(options.compare) |
| 291 | : new BinarySearchTree()) as BinarySearchTree<U>; |
| 292 | unmappedValues = collection; |
| 293 | } |
| 294 | const values: Iterable<U> = options?.map |
| 295 | ? Array.from(unmappedValues, options.map, options.thisArg) |
| 296 | : unmappedValues as U[]; |
| 297 | for (const value of values) result.insert(value); |
| 298 | return result; |
| 299 | } |
| 300 | |