zip
EditGroups values that share the same index across multiple arrays.
export type ZipMode = "shortest" | "longest";export type Zipped<Arrays extends readonly (readonly unknown[])[]> = { -readonly [ Index in keyof Arrays ]: Arrays[Index] extends readonly (infer Value)[] ? Value : never;};export type ZippedLongest<Arrays extends readonly (readonly unknown[])[]> = { -readonly [ Index in keyof Arrays ]: Arrays[Index] extends readonly (infer Value)[] ? Value | undefined : never;};
/** Groups values at matching indexes across multiple arrays. */export const zip = < const Arrays extends readonly (readonly unknown[])[], const Mode extends ZipMode = "shortest",>( arrays: Arrays, { mode = "shortest" as Mode }: { mode?: Mode } = {},): Array<Mode extends "longest" ? ZippedLongest<Arrays> : Zipped<Arrays>> => { if (mode !== "shortest" && mode !== "longest") { throw new RangeError("mode must be shortest or longest"); } const denseArrays: unknown[][] = []; for (let arrayIndex = 0; arrayIndex < arrays.length; arrayIndex += 1) { if (!Object.hasOwn(arrays, arrayIndex)) { throw new TypeError("arrays must not contain empty slots"); } const array = arrays[arrayIndex]; if (!Array.isArray(array)) { throw new TypeError("arrays must contain only arrays"); } const dense: unknown[] = []; for (let index = 0; index < array.length; index += 1) { if (!Object.hasOwn(array, index)) { throw new TypeError("input arrays must not contain empty slots"); } dense.push(array[index]); } denseArrays.push(dense); } if (denseArrays.length === 0) return [];
const lengths = denseArrays.map((array) => array.length); const rowCount = mode === "longest" ? Math.max(...lengths) : Math.min(...lengths); const rows: unknown[][] = [];
for (let index = 0; index < rowCount; index += 1) { rows.push(denseArrays.map((array) => array[index])); }
return rows as Array< Mode extends "longest" ? ZippedLongest<Arrays> : Zipped<Arrays> >;};Download
Section titled “Download”wget -O src/lib/zip.ts https://raw.githubusercontent.com/jrTilak/lazykit/HEAD/registry/functions/zip.tstemp_dir="$(mktemp -d)" && bunx degit jrTilak/lazykit/registry/functions "$temp_dir" && mv "$temp_dir/zip.ts" src/lib/zip.ts && rm -r "$temp_dir"Examples
Section titled “Examples”import { zip } from "./zip";
const arrays = [[1, 2, 3], ["a", "b", "c", "d"]];const result = zip(arrays);
console.log(result);// Output: [[1, "a"], [2, "b"], [3, "c"]]import { zip } from "./zip";
const arrays = [[1, 2, 3], ["x", "y"]];const strictResult = zip(arrays);
console.log(strictResult);// Output: [[1, "x"], [2, "y"]]import { zip } from "./zip";
const arrays = [[1, 2, 3], ["a", "b", "c", "d"], [true, false]];const result = zip(arrays, { mode: "longest" });
console.log(result);// Output: [[1, "a", true], [2, "b", false], [3, "c", undefined], [undefined, "d", undefined]]import { zip } from "./zip";
const arrays = [[1, 2, 3], ["x", "y", "z"], [10, 20]];const strictResult = zip(arrays);
console.log(strictResult);// Output: [[1, "x", 10], [2, "y", 20]]arrays(readonly (readonly unknown[])[]) — Dense arrays whose values should be grouped by index. Sparse outer or inner arrays are rejected.options.mode("shortest" | "longest", default:"shortest") — Stops at the shortest input or continues to the longest and insertsundefinedfor missing values.
Returns
Section titled “Returns”An array of tuples, one for each included index.