我正在玩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
方法应该以这种方式使用。有更好的解决方案吗?
答案 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!只有设置,推送,弹出,移位,非移位和合并可能 突然使用。