11

Is there a way to separate an ImmutableJS list into a list of multiple lists ? I'm basically looking for something like lodash's chunk but for ImmutableJS lists.

I could transform my list into an Array before passing it to chunk and convert back the response to an ImmutableJS list, but I'm told shallow transformations are not efficient and my lists are quite big.

Thank you, G.

Gerard Clos
  • 1,080
  • 2
  • 12
  • 21

4 Answers4

14

Immutable.js does not provide it right out of the box.

Here’s the function which splits the list into equally sized chunks. The last chunk may be smaller if the list can not be split evenly.

function splitIntoChunks(list, chunkSize = 1) {
  return Immutable.Range(0, list.count(), chunkSize)
    .map(chunkStart => list.slice(chunkStart, chunkStart + chunkSize));
}

It first enumerates the indexes where each chunk should start and then transforms the list of indexes into a list of slices spanning from each index to the index plus chunk size.

Looks simple and efficient to me.

jokka
  • 1,832
  • 14
  • 12
1

mudash (a lodash wrapper that provides immutable js support) provides a chunk method. It should give you what you need. No transformations performed so performance remains high.

import _ from 'mudash'
import Immutable from 'immutable'

const list = Immutable.List([1, 2, 3, 4])
_.chunk(list, 2) // List [ List [ 1, 2 ], List [ 3, 4 ] ]

Full disclosure, I am the author of the mudash module.

Brian Neisler
  • 843
  • 9
  • 12
0

This chunk function from this thread seems to work well with my immutable data out of the box.

function chunk(chunkSize, array) {
    return array.reduce(function(previous, current) {
        var chunk;
        if (previous.length === 0 ||
            previous[previous.length -1].length === chunkSize) {
            chunk = [];   // 1
            previous.push(chunk);   // 2
        }
        else {
            chunk = previous[previous.length -1];   // 3
        }
        chunk.push(current);   // 4
        return previous;   // 5
    }, []);   // 6
}

var list = Immutable.fromJS(['something','nothing','anything','hello'])

console.log(chunk(3,list))

Example: https://jsfiddle.net/lau_chung/c67g7469/2/

Community
  • 1
  • 1
RedGiant
  • 4,444
  • 11
  • 59
  • 146
0

I've just come across this problem too and I solved it with writing this function:

const getListAsChunks = (list, chunkSize) => {
    const iterations = Math.ceil(list.count() / chunkSize);

    return range(0, iterations).reduce((all, item, i) => {
        const start = i * chunkSize;
        const end = (i + 1) * chunkSize;
        return all.push(list.slice(start, end));
    }, List());
};

Then call it like so:

const myChunkedList = getListAsChunks(myImmutableList, 5);

I imported range from lodash/range and List from immutable Hope this helps.

Quizzy
  • 46
  • 5