我正在使用 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);
然而这看起来有点老套。我认为 filter
方法不应该以这种方式使用。有更好的解决办法吗?
最佳答案
假设这里 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
:
Note: Not all methods can be used on a mutable collection or within withMutations! Only set, push, pop, shift, unshift and merge may be used mutatively.
关于javascript - 使用 Immutable.js 将元素从一个列表移动到另一个列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30717911/