teles/array-mixer
Clean project logo, badges. Table of contents. Contribution section. Many illustrated examples.
ArrayMixer is a tiny TypeScript-friendly utility (< 1 kB gzipped) for interleaving any number of arrays in a fully customizable order.
Powerful, dependency-free, and easy to use.
Table of contents
- What's new in v1
- Installation
- Playground
- Quick start
- API
- Examples
- TypeScript support
- Contributing
- License
What's new in v1
The previous ArrayMixer(aliases, sequence) API based on a string mini-DSL (["2C", "4M"]) was replaced by a clean, type-safe tuple-based API:
// before (v0.x)
ArrayMixer({ P: photos, A: ads }, ["2P", "1A"]);
// after (v1.x)
arrayMixer([2, photos], [1, ads]);
Why the change:
- No mini-DSL — sequences are plain data, no string parsing.
- No aliases — the source array is right there in the entry.
- Generic types — the result type is inferred from the inputs.
- Options object — opt into
limit,shuffle, andfillstrategies.
Installation
pnpm add array-mixer
import { arrayMixer } from "array-mixer";
CommonJS, ESM, and a UMD bundle are all shipped. For a <script> tag:
<script src="https://unpkg.com/array-mixer/release/array-mixer.umd.js"></script>
<script>
const mixed = ArrayMixer.arrayMixer([2, photos], [1, ads]);
</script>
Playground
Try the tuple API with emoji cards in the ArrayMixer Playground.
Quick start
Given two arrays, photos (12 items) and ads (6 items):
photos.length === 12; // true
ads.length === 6; // true
Interleave 2 photos followed by 1 ad until both arrays are consumed:
const mixed = arrayMixer([2, photos], [1, ads]);
mixed will contain:
API
arrayMixer(...entries, options?)
Reorder one or more arrays into a single array by interleaving chunks of each.
function arrayMixer<T>(...entries: MixEntry<T>[]): T[];
function arrayMixer<T>(
...args: [...MixEntry<T>[], MixerOptions]
): T[];
The optional options object is detected automatically as the last argument when it is not a MixEntry tuple.
MixEntry<T>
type MixEntry<T> = readonly [count: number, items: readonly T[]];
A tuple with two fields:
count— how many items of this group to emit per round. Must be a positive integer.items— the source array.
MixerOptions
interface MixerOptions {
limit?: number;
shuffle?: boolean;
fill?: "repeat" | "skip" | "stop";
}
| Option | Default | Description |
|---|---|---|
limit |
sum of input lengths | Forces a fixed result length. Useful for infinite feeds. |
shuffle |
false |
Shuffles each input array (Fisher–Yates) before mixing. Inputs are not mutated. |
fill |
"repeat" |
What to do when an entry's source runs out: "repeat" cycles from the start, "skip" removes that group from further rounds, "stop" ends the result. |
Invalid runtime input throws clear errors:
countmust be a positive integer.limit, when provided, must be a non-negative integer.fill, when provided, must be"repeat","skip", or"stop".
Examples
1) For every 7 photos display an ad
arrayMixer([7, photos], [1, ads]);
2) For every 4 paragraphs include 2 images
arrayMixer([4, paragraphs], [2, images]);
3) In a group of 8 related links, reserve positions 5–6 for sponsored
arrayMixer([4, related], [2, sponsored], [2, related]);
4) Display a list of songs with hits sprinkled in
arrayMixer([10, songs], [2, hits]);
5) Cycle puppies, kittens, and penguins in sequence
const mixed = arrayMixer([1, puppies], [1, kittens], [1, penguins]);
puppies |
kittens |
penguins |
mixed |
|---|---|---|---|
| [🐶, 🐶, 🐶] | [🐱, 🐱, 🐱] | [🐧, 🐧, 🐧] | [🐶, 🐱, 🐧, 🐶, 🐱, 🐧, 🐶, 🐱, 🐧] |
6) 1 large photo for every 2 medium followed by 3 small
arrayMixer([2, medium], [3, small], [1, large]);
7) Cap an infinite feed with limit
arrayMixer([3, articles], [1, ads], { limit: 20 });
The result is exactly 20 items long; arrays cycle as needed (fill: "repeat" is the default).
8) Stop when any source runs out
arrayMixer(
[2, [1, 2, 3, 4]],
[1, [9]],
{ fill: "stop", limit: 100 },
);
// => [1, 2, 9, 3, 4]
9) Drop exhausted groups, keep the rest going
arrayMixer(
[1, ["a", "b"]],
[1, ["x", "y", "z", "w"]],
{ fill: "skip" },
);
// => ["a", "x", "b", "y", "z", "w"]
10) Shuffle each source before mixing
arrayMixer([2, ads], [5, articles], { shuffle: true });
TypeScript support
The result type is inferred from the inputs:
const mixed = arrayMixer([2, ["red", "blue"]], [1, ["cat", "dog"]]);
// mixed: string[]
interface Photo { url: string }
const photos: Photo[] = [/* ... */];
const ads: Photo[] = [/* ... */];
const feed = arrayMixer([2, photos], [1, ads]);
// feed: Photo[]
Contributing
You may contribute in many ways: new features, bug fixes, documentation improvements, or translations. See CONTRIBUTING.md.
License
MIT — Jota Teles