Home Reference Source Test

src/main/generic/utils/array/ArrayUtils.js

class ArrayUtils {
    /**
     * @template T
     * @param {Array.<T>} arr
     * @return {T}
     */
    static randomElement(arr) {
        return arr[Math.floor(Math.random() * arr.length)];
    }

    /**
     * @param {Uint8Array} uintarr
     * @param {number} begin
     * @param {number} end
     * @return {Uint8Array}
     */
    static subarray(uintarr, begin, end) {
        function clamp(v, min, max) { return v < min ? min : v > max ? max : v; }

        if (begin === undefined) { begin = 0; }
        if (end === undefined) { end = uintarr.byteLength; }

        begin = clamp(begin, 0, uintarr.byteLength);
        end = clamp(end, 0, uintarr.byteLength);

        let len = end - begin;
        if (len < 0) {
            len = 0;
        }

        return new Uint8Array(uintarr.buffer, uintarr.byteOffset + begin, len);
    }

    /**
     * @param {Array} list
     * @param {number} k
     * @return {Generator}
     */
    static *k_combinations(list, k) {
        const n = list.length;
        // Shortcut:
        if (k > n) {
            return;
        }
        const indices = Array.from(new Array(k), (x,i) => i);
        yield indices.map(i => list[i]);
        const reverseRange = Array.from(new Array(k), (x,i) => k-i-1);
        /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
        while (true) {
            let i = k-1, found = false;
            for (i of reverseRange) {
                if (indices[i] !== i + n - k) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                return;
            }
            indices[i] += 1;
            for (const j of Array.from(new Array(k-i-1), (x,k) => i+k+1)) {
                indices[j] = indices[j-1] + 1;
            }
            yield indices.map(i => list[i]);
        }
    }
}
Class.register(ArrayUtils);