Whilst working on a sketch app (now abandoned, I’m afraid - interest got lost after the most exciting mathematical geometry part was mostly done), I came up with the problem of devising a decent way of calculating combinations from an array. No premade solution was satistifactory, so..

import { clone } from "lodash-es";

/**
 * Based on: https://stackoverflow.com/a/16256122
 * @param arr Array to select from
 * @param k K out of N
 */
export function combinations<T>(arr: ReadonlyArray<T>, k: number): Array<Array<T>> {
    // Short-circuit for common issues
    if (arr.length < 1 || k > arr.length || k < 1) return [];

    // Result holder
    const results: Array<Array<T>> = [];

    // Interim value holder
    const interimValue: Array<T> = Array(k);

    // Inner iteration function
    const inner = function (arr: ReadonlyArray<T>, k: number, startPos: number) {
        if (k == 0) {
            results.push(clone(interimValue));
            return;
        }
        for (let i = startPos; i <= arr.length - k; i++) {
            interimValue[interimValue.length - k] = arr[i];
            inner(arr, k - 1, i + 1);
        }
    };

    // Start iterating, and return the result
    inner(arr, k, 0);
    return results;
}


© Arttu Ylä-Sahra 2016-2021
Page rendered on 2021-06-15T18:07:29.351+00:00