使用Immutable.js

时间:2015-06-08 19:55:04

标签: javascript immutable.js

我正在玩Immutable.js。我遇到了这个问题而且我找不到一个好的解决方案:我有两个列表,A和B,我想使用自定义predicate函数从列表A中过滤掉一些元素并添加它们列表B.两者都是不可变的。

这里显而易见的问题是A.filter(predicate)的返回值是一个新的更新实例,删除的元素将丢失。我可以先添加那些过滤后的元素:

B = B.concat(A.filterNot(predicate));
A = A.filter(predicate);

这意味着两次在原始列表上循环。解决这个问题的唯一方法是为过滤功能添加副作用:

let tmp = [];
B = B.filter(el => { 
    if (!predicate(el)) {
        tmp.push(el);
        return false;
    } else return true;
});
A = A.concat(tmp);

然而,这看起来有点hacky。我不认为filter方法应该以这种方式使用。有更好的解决方案吗?

1 个答案:

答案 0 :(得分:3)

假设这里B是你要过滤的数组,而A得到了连接到它的过滤元素:(就像你的第二个代码示例),我认为这是你能做的最好的。

A.withMutations( (list) => {
  B = B.filter( 
    (el) => { 
      if (!predicate(el)) {
          list.push(el);
          return false;
      } else return true;
    }
  );
  return list;
});

或者说可读性更高:

A.withMutations( (list) => {
  B = B.filter( (el) => { return (!predicate(el)) ? !!list.push(el) : true; 
      });
  return list;
});

如果您发现自己经常将项目从一个列表移动到另一个列表,最好编写一个方法,transferTo执行上述操作。

来自withMutations

  

注意:并非所有方法都可用于可变集合或其中   withMutations!只有设置,推送,弹出,移位,非移位和合并可能   突然使用。