1. ホーム
  2. javascript

[解決済み] JSの配列をN個の配列に分割する

2023-01-07 16:47:17

質問

このようなJS配列があるとします。

var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

私が欲しいのは、その配列をN個の小さな配列に分割することです。例えば

split_list_in_n(a, 2)
[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11]]

For N = 3:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11]]

For N = 4:
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]]

For N = 5:
[[1, 2, 3], [4, 5], [6, 7], [8, 9], [10, 11]]

Pythonの場合は、こんな感じです。

def split_list_in_n(l, cols):
    """ Split up a list in n lists evenly size chuncks """
    start = 0
    for i in xrange(cols):
        stop = start + len(l[i::cols])
        yield l[start:stop]
        start = stop

JSの場合、私が思いついた最も正しい解決策は再帰的な関数ですが、複雑で醜いので好きではありません。この内部関数はこのような配列 [1, 2, 3, null, 4, 5, 6, null, 7, 8] を返し、私はそれをもう一度ループして手動で分割しなければなりません。(私の最初の試みはこれを返していました。[1, 2, 3, [4, 5, 6, [7, 8, 9]]] を返していたので、nullセパレータで行うことにしました)。

function split(array, cols) {
    if (cols==1) return array;
    var size = Math.ceil(array.length / cols);
    return array.slice(0, size).concat([null]).concat(split(array.slice(size), cols-1));
}

以下はそのjsfiddleです。 http://jsfiddle.net/uduhH/

どのようにするのですか?ありがとうございます!

どのように解決するのですか?

スライスを "balanced"(サブアレイの長さの差をできるだけ小さくする)または "even"(最後のサブアレイ以外はすべて同じ長さ)にすることができます。

function chunkify(a, n, balanced) {
    
    if (n < 2)
        return [a];

    var len = a.length,
            out = [],
            i = 0,
            size;

    if (len % n === 0) {
        size = Math.floor(len / n);
        while (i < len) {
            out.push(a.slice(i, i += size));
        }
    }

    else if (balanced) {
        while (i < len) {
            size = Math.ceil((len - i) / n--);
            out.push(a.slice(i, i += size));
        }
    }

    else {

        n--;
        size = Math.floor(len / n);
        if (len % size === 0)
            size--;
        while (i < size * n) {
            out.push(a.slice(i, i += size));
        }
        out.push(a.slice(size * n));

    }

    return out;
}


///////////////////////

onload = function () {
    function $(x) {
        return document.getElementById(x);
    }

    function calc() {
        var s = +$('s').value, a = [];
        while (s--)
            a.unshift(s);
        var n = +$('n').value;
        $('b').textContent = JSON.stringify(chunkify(a, n, true))
        $('e').textContent = JSON.stringify(chunkify(a, n, false))
    }

    $('s').addEventListener('input', calc);
    $('n').addEventListener('input', calc);
    calc();
}
<p>slice <input type="number" value="20" id="s"> items into
<input type="number" value="6" id="n"> chunks:</p>
<pre id="b"></pre>
<pre id="e"></pre>