All files / collections / unstable_interleave.ts

100.00% Branches 13/13
100.00% Functions 1/1
100.00% Lines 22/22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x3
x3
 
x12
x12
 
x11
x11
x12
x25
x25
x25
x25
 
x11
x11
 
x12
x29
x63
x49
x49
x63
x29
 
x11
x12

































































// Copyright 2018-2026 the Deno authors. MIT license.
// This module is browser compatible.

/**
 * Merges multiple arrays into a single array by round-robin picking one
 * element from each source in turn. Unlike {@linkcode zip}, which stops at
 * the shortest array and produces tuples, `interleave` continues through
 * all elements and returns a flat array.
 *
 * @experimental **UNSTABLE**: New API, yet to be vetted.
 *
 * @typeParam T Tuple of element types, one per input array; result is
 * `T[number][]`.
 *
 * @param arrays The arrays to interleave.
 * @returns A new array containing elements from all input arrays in
 * round-robin order.
 *
 * @example Basic usage
 * ```ts
 * import { interleave } from "@std/collections/unstable-interleave";
 * import { assertEquals } from "@std/assert";
 *
 * const numbers = [1, 2, 3];
 * const letters = ["a", "b", "c"];
 *
 * assertEquals(interleave(numbers, letters), [1, "a", 2, "b", 3, "c"]);
 * ```
 *
 * @example Unequal-length arrays
 * ```ts
 * import { interleave } from "@std/collections/unstable-interleave";
 * import { assertEquals } from "@std/assert";
 *
 * assertEquals(
 *   interleave([1, 2, 3], ["a", "b"], [true]),
 *   [1, "a", true, 2, "b", 3],
 * );
 * ```
 */
export function interleave<T extends unknown[]>(
  ...arrays: { [K in keyof T]: ReadonlyArray<T[K]> }
): T[number][] {
  const arrayCount = arrays.length;
  if (arrayCount === 0) return [];

  let maxLength = 0;
  let totalLength = 0;
  for (let i = 0; i < arrayCount; ++i) {
    const len = arrays[i]!.length;
    totalLength += len;
    if (len > maxLength) maxLength = len;
  }

  const result: T[number][] = new Array(totalLength);
  let k = 0;

  for (let i = 0; i < maxLength; ++i) {
    for (let j = 0; j < arrayCount; ++j) {
      if (i < arrays[j]!.length) {
        result[k++] = arrays[j]![i] as T[number];
      }
    }
  }

  return result;
}