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?
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?
Share Improve this question edited Dec 15, 2017 at 2:43 PatS asked Dec 15, 2017 at 1:19 PatSPatS 11.6k17 gold badges70 silver badges122 bronze badges 1- When implementing my solution, I realized that Javascript Set doesn't provide a way to get an item in the set based on an index. So I created a class called Looper with three methods constructor(anObj), length() caches (if necessary) and returns length, and get(idx) that returns an item at a given index. I'll update the question to reflect this information. – PatS Commented Dec 15, 2017 at 2:40
2 Answers
Reset to default 5You 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()
andreturn true
to break
You could prototype and create your own list that had a length function that returns the size. You can also override through prototype the forEach method on an array to break out.
The only other way which I can think of that isn't super clean, is to get the length or size of the object before calling the function that loop over the object and send it in as a parameter.