【问题标题】:Can I loop over an immutable.List, immutable.Set or Javascript Array or Set using same code?我可以使用相同的代码遍历 immutable.List、immutable.Set 或 Javascript 数组或 Set 吗?
【发布时间】:2017-12-15 01:19:29
【问题描述】:

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

由于我不会深入探讨的原因,我希望能够在不考虑底层集合的情况下循环这些项目。

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

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

对于 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;
}

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

对于那些建议使用这些对象中的每一个都可用的 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;
}

我看过的一些内容包括:

有没有其他人试图解决这个问题,如果有,他们是如何解决这个问题的?

【问题讨论】:

  • 在实现我的解决方案时,我意识到 Javascript Set 没有提供基于索引获取集合中项目的方法。因此,我创建了一个名为 Looper 的类,它具有三个方法构造函数(anObj)、length() 缓存(如果需要)并返回长度,以及 get(idx) 返回给定索引处的项目。我将更新问题以反映此信息。

标签: javascript immutable.js


【解决方案1】:

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

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

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

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

您可能还想阅读How to short circuit Array.forEach like calling break。它列出了几个解决方案,包括 for...of,它们应该适用于您要使用的所有集合:

  • 将循环包装在try 中并抛出异常以中断
  • 使用.some()return true 破解

【讨论】:

    【解决方案2】:

    您可以原型化并创建自己的列表,该列表具有返回大小的长度函数。您还可以通过原型覆盖数组上的 forEach 方法来突破。

    我能想到的唯一另一种方法不是超级干净,是在调用循环对象并将其作为参数发送的函数之前获取对象的长度或大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      相关资源
      最近更新 更多