2015-06-08 131 views
2

我在玩Immutable.js。我遇到了这个问题,我无法找到一个很好的解决方案:我有两个列表A和B,我想使用自定义的predicate函数从列表A中筛选出一些元素,并将它们添加到列表B中两者都是不变的。使用Immutable.js将元素从一个列表移动到另一个列表

这里显而易见的问题是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方法应该以这种方式使用。有更好的解决方案吗?

+0

为什么不只是迭代将它分成两个临时数组?所以基本上,A上的'.each'迭代? – Cymen

回答

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使用!只有设置,推送,弹出,移位,不移位和合并可能是 突变使用。

+0

谢谢,这绝对看起来更好,虽然核心思想是一样的。 – tobik

相关问题