我可以使用相同的代码循环访问 immutable.List、immutable.Set 或 Javascript Array 或 Set 吗?

Pat*_*atS 4 javascript immutable.js

我正在编写一些使用许多不同项目“列表”的 NodeJS 代码。底层实现使用包括 Immutable.List、Immutable.Set、Javascript Array 和 Javascript Set。

由于我不会详细讨论的原因,我希望能够循环这些项目而不考虑底层集合。

一些背景可能会有用。对于数组,我可以使用以下代码来循环 Javascript 数组。

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

对于 Immutable.List,我需要使用 Immutable.List.size 属性(而不是 length 属性)并使用“Immutable.List.get”函数,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

除了一些小的差异之外,循环逻辑非常接近。

对于那些建议使用每个对象上可用的 forEach() 方法的自然答案的人。普通的 Javascript Array.forEach()方法不会处理跳出循环(这种情况需要Array.some()方法)。Immutable.List 基于 Immutable.Collection.forEach 它支持“打破”循环,因此这可能有效,但需要将 Javascript 对象包装到不可变序列/集合中。我是使用 Immutable 库的新手,因此可能有另一种方法对于熟悉 Immutable 的人来说是众所周知的。

接下来描述我正在考虑的方法。我正在考虑一个提供解决方案的实用函数,如下所示:

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

我看过的一些内容包括:

有其他人尝试过解决这个问题吗?如果是的话,他们是如何解决这个问题的?

Sim*_*der 5

你可以使用for...of循环。这允许您操作任何Iterable对象,其中包括内置集合以及 Immutable.js 集合。

for (let element of collection) {
    // do something with element
    if (someCondition) {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

for它不会让您像常规循环那样访问迭代索引forEach,但这很容易跟踪您自己:

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

您可能还想阅读如何像调用break一样短路Array.forEach。它列出了几个解决方案,其中包括for...of应该适用于您想要使用的所有集合的解决方案:

  • 将循环包裹起来try并抛出异常来中断
  • 使用.some()return true打破