* @param containedIn: An set containing objects on the reference path currently * being processed (used to detect cycles).
(
inputs: any[], zipFn: (xs: any[]) => DeepMapResult,
containedIn: Set<{}> = new Set())
| 140 | * being processed (used to detect cycles). |
| 141 | */ |
| 142 | function deepZipInternal( |
| 143 | inputs: any[], zipFn: (xs: any[]) => DeepMapResult, |
| 144 | containedIn: Set<{}> = new Set()): any|any[] { |
| 145 | // The recursion follows the structure of input 0; it's assumed that all the |
| 146 | // other inputs have the same structure. |
| 147 | const input = inputs[0]; |
| 148 | if (containedIn.has(input)) { |
| 149 | throw new Error('Circular references are not supported.'); |
| 150 | } |
| 151 | const result = zipFn(inputs); |
| 152 | |
| 153 | if (result.recurse && result.value !== null) { |
| 154 | throw new Error( |
| 155 | 'A deep zip function may not return both a value and recurse=true.'); |
| 156 | } |
| 157 | |
| 158 | if (!result.recurse) { |
| 159 | return result.value; |
| 160 | } else if (isIterable(input)) { |
| 161 | // tslint:disable-next-line:no-any |
| 162 | const mappedIterable: any|any[] = Array.isArray(input) ? [] : {}; |
| 163 | containedIn.add(input); |
| 164 | for (const k in input) { |
| 165 | const children = inputs.map(x => x[k]); |
| 166 | const childResult = deepZipInternal(children, zipFn, containedIn); |
| 167 | mappedIterable[k] = childResult; |
| 168 | } |
| 169 | containedIn.delete(input); |
| 170 | return mappedIterable; |
| 171 | } else { |
| 172 | throw new Error(`Can't recurse into non-iterable type: ${input}`); |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | // tslint:disable-next-line:no-any |
| 177 | export function zipToList(x: any[]): DeepMapResult { |
no test coverage detected
searching dependent graphs…