Skip to content

Commit 57a48c3

Browse files
committed
Add zip and unzip functions
1 parent d3e8758 commit 57a48c3

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/arrays.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,59 @@ export function join<T = unknown>(...arrays: T[][]): T[] {
158158
return arrays.reduce((a, x) => a.concat(x), []);
159159
}
160160

161+
/** Turn a 2-tuple of lists into a list of 2-tuples. For example: `[['a', 'b', 'c'], [1, 2, 3]]` becomes `[['a', 1], ['b', 2], ['c', 3]]` */
162+
export function zip2<A, B>(lists: [A[], B[]]) {
163+
return zipAny(lists) as Array<[A, B]>;
164+
}
165+
166+
/** Turn a 3-tuple of lists into a list of 3-tuples. */
167+
export function zip3<A, B, C>(lists: [A[], B[], C[]]) {
168+
return zipAny(lists) as Array<[A, B, C]>;
169+
}
170+
171+
/** Turn a 4-tuple of lists into a list of 4-tuples. */
172+
export function zip4<A, B, C, D>(lists: [A[], B[], C[], D[]]) {
173+
return zipAny(lists) as Array<[A, B, C, D]>;
174+
}
175+
176+
/** Turn a n-tuple of lists into a list of n-tuples. */
177+
export function zipAny(lists: any[][]) {
178+
const zipped = lists[0].map(() => []) as any[][];
179+
// eslint-disable-next-line guard-for-in
180+
for (const [index, zippedList] of zipped.entries()) {
181+
for (const list of lists) {
182+
zippedList.push(list[index]);
183+
}
184+
}
185+
return zipped;
186+
}
187+
188+
/** Turn a list of 2-tuples into a 2-tuple of lists. For example: `[['a', 1], ['b', 2], ['c', 3]]` becomes `[['a', 'b', 'c'], [1, 2, 3]]` */
189+
export function unzip2<A, B>(tuples: Array<[A, B]>) {
190+
return unzipAny(tuples) as [A[], B[]];
191+
}
192+
193+
/** Turn a list of 3-tuples into a 3-tuple of lists. */
194+
export function unzip3<A, B, C>(tuples: Array<[A, B, C]>) {
195+
return unzipAny(tuples) as [A[], B[], C[]];
196+
}
197+
198+
/** Turn a list of 4-tuples into a 4-tuple of lists. */
199+
function unzip4<A, B, C, D>(tuples: Array<[A, B, C, D]>) {
200+
return unzipAny(tuples) as [A[], B[], C[], D[]];
201+
}
202+
203+
/** Turn a list of n-tuples into a n-tuple of lists. */
204+
function unzipAny(tuples: any[][]) {
205+
const init = tuples.map(() => []) as any[][];
206+
return tuples.reduce(
207+
(unzipped: any[][], tuple) => {
208+
return tuple.map((elem, index) => [...unzipped[index], elem]);
209+
},
210+
init
211+
);
212+
}
213+
161214
type LinkedListItem<T> = {val: T, prev: LinkedListItem<T>, next: LinkedListItem<T>};
162215

163216
/** Converts an array to a linked list data structure. */

0 commit comments

Comments
 (0)