Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I loop over an immutable.List, immutable.Set or Javascript Array or Set using same code?

I'm working on some NodeJS code that uses many different "lists" of items. The underlying implementation uses including Immutable.List, Immutable.Set, Javascript Array and Javascript Set.

For reasons I won't go into, I would like to be able to loop over these items without regard to the underlying collection.

Some background might be useful. For Array, I can use the following to loop over a Javascript Array.

let anArray = [ new SomeObj(), new SomeObj(), ... ]
for(let idx=0; idx < anArray.length; idx++){
    let someObj = anArray[idx];
    // ... etc
    if (someCondition) break;
}

For the Immutable.List, I need to use the Immutable.List.size property (instead of the length property) and use "Immutable.List.get" function as follows:

const immutable = require('immutable');

let aList = immutable.List([ new SomeObj(), new SomeObj(), ... ]);
for(idx=0; idx < aList.size; idx++){
    var item = aList.get(idx);
    // ... etc
    if (someCondition) break;
}

The looping logic is VERY close except for some small differences.

For those who would suggest the natural answer of using the forEach() method that is available on each of these objects. The normal Javascript Array.forEach() method doesn't handle breaking out of the loop (the Array.some() method is needed for that situation). The Immutable.List is based on a Immutable.Collection.forEach that does support "breaking" out of the loop so this might work but would require wrapping the Javascript objects into a Immutable sequence/collection. I'm new to using the Immutable library so there might be another approach that is well known to those familiar with Immutable.

The approach I'm considering is described next. I'm thinking of a utility function that provides the solution as follows:

for(let idx=0, looper=new Looper(aListOrSet); idx < looper.length(); idx++){
    var item = looper.get(idx);
    // ... etc
    if (someCondition) break;
}

Some things I've looked at include:

  • How to loop through Immutable List like forEach
  • Immutable.Collection.forEach
  • Immutable Sequences - This might be the trick. I would have to convert the Javascript objects to an immutable sequence, but this might work.

Has anyone else tried to solve this, and if so how did they solve this problem?

like image 1000
PatS Avatar asked Oct 24 '25 16:10

PatS


1 Answers

You could use a for...of loop. This allows you operate on any Iterable object, which includes built-in collections as well as Immutable.js collections.

for (let element of collection) {
    // do something with element
    if (someCondition) {
        break;
    }
}

It doesn't give you access to the index of iteration like a regular for loop or forEach would, but that's easy enough to keep track of yourself:

let i = 0;
for (let element of collection) {
    // do something with element
    if (someCondition) {
        break;
    }
    i++;
}

You might also want to read How to short circuit Array.forEach like calling break. It lists a couple solutions including for...of that should work with all the collections you want to use:

  • Wrap the loop in try and throw an exception to break
  • Use .some() and return true to break
like image 169
Simon Baumgardt-Wellander Avatar answered Oct 26 '25 06:10

Simon Baumgardt-Wellander



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!