dtechplus
dtechplus

Reputation: 599

Split Javascript array elements into chunks at designated indexes

I have an array like so

const arr = [3,6,9,12,18,21,24,27,33,36];

I want the array arr split into chunks at 12, 21 and 33. That is at the index 3, 5, and 8. I want to produce another array chunks looking like this..

const chunks = [[3,6,9,12],[18,21],[24,27,33],[36]];

The solutions I have seen here basically split arrays into 'n' chunks. Basically I want to split at arrays at several (specified) indexes.

I do not mind an underscore.js/lodash solution. Thanks

Upvotes: 1

Views: 2500

Answers (4)

Slai
Slai

Reputation: 22866

slice can be used to get part of array:

const arr = [3, 6, 9, 12, 18, 21, 24, 27, 33, 36], indexes = [0, 4, 6, 9];

const chunks = indexes.map((_, i, a) => arr.slice(_, a[i + 1]));

console.log( JSON.stringify(chunks) );

Upvotes: 3

Sebastian Simon
Sebastian Simon

Reputation: 19475

You could use reduceRight and decide which elements to split at. Since you’re providing the last values of a sub-array rather than the first ones, going from right to left is actually a bit easier, hence I use a reduceRight rather than a reduce.

Split by value

const arr = [3, 6, 9, 12, 18, 21, 24, 27, 33, 36],
  splitValues = [12, 21, 33],
  chunks = arr.reduceRight((result, value) => {
    result[0] = result[0] || [];

    if (splitValues.includes(value)) {
      result.unshift([value]);
    } else {
      result[0].unshift(value);
    }

    return result;
  }, []);

console.log(chunks);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Split by index

const arr = [3, 6, 9, 12, 18, 21, 24, 27, 33, 36],
  splitIndexes = [3, 5, 8],
  chunks = arr.reduceRight((result, value, index) => {
    result[0] = result[0] || [];

    if (splitIndexes.includes(index)) {
      result.unshift([value]);
    } else {
      result[0].unshift(value);
    }

    return result;
  }, []);

console.log(chunks);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 7

Evan Trimboli
Evan Trimboli

Reputation: 30082

Here's an alternative way of doing it that I think is a bit clearer.

function chunkIt(arr, indexes) {
    const ret = [];
    let last = 0;

    indexes.forEach(i => {
        ret.push(arr.slice(last, i + 1));
        last = i + 1;
    });
    if (last < arr.length) {
        ret.push(arr.slice(last));
    }
    return ret;
}

console.log(chunkIt([3,6,9,12,18,21,24,27,33,36], [3,5,8]));

Upvotes: 3

CRice
CRice

Reputation: 32146

const arr = [3,6,9,12,18,21,24,27,33,36];

// Important: this array gets mutated. Make a copy if that's not okay.
const inds = [3,5,8];

const chunked = arr.reduce((p, c, i) => { if (i-1 === inds[0]) { inds.shift(); p.push([]); } p[p.length-1].push(c); return p; }, [[]]);

console.log(chunked)

Upvotes: 3

Related Questions