Javascript Immutable.js:如何使用WithTranslations同时构建两个数据结构
Immutable.js有一个很好的特性,允许您使用临时可变对象构建复杂的不可变对象,以避免在构建过程中创建新引用 这非常适合转换以下内容:Javascript Immutable.js:如何使用WithTranslations同时构建两个数据结构,javascript,immutable.js,Javascript,Immutable.js,Immutable.js有一个很好的特性,允许您使用临时可变对象构建复杂的不可变对象,以避免在构建过程中创建新引用 这非常适合转换以下内容: // Bad way var goodThing = badThing.set("something", 123); goodThing = goodThing.set("somethingElse", 456"); goodThing = goodThing.set("anotherThing", 789"); ... // Good way var
// Bad way
var goodThing = badThing.set("something", 123);
goodThing = goodThing.set("somethingElse", 456");
goodThing = goodThing.set("anotherThing", 789");
...
// Good way
var goodThing = badThing.withMutations(function(bt) {
bt.set("something", 123);
bt.set("somethingElse", 456);
bt.set("anotherThing", 789);
...
});
但是如果我想同时创建两个对象呢
// What I have now
var list1 = List();
var list2 = List();
someStuff.forEach(function(value, key) {
list1 = list1.push(value.id);
list2 = list2.push(key);
});
// The best I've come up with...
var list1 = List();
var list2 = List();
list1 = list1.withMutations(function(l1) {
list2 = list2.withMutations(function(l2) {
someStuff.forEach(function(value, key) {
l1.push(value.id);
l2.push(key);
});
});
});
到目前为止,我想到的最好的办法是用突变调用来包装,但这隐藏了正在发生的事情的含义,而且看起来很可怕和混乱。有没有一种方法可以将多个对象传递到一个调用中?如果不是,实现这一点的最佳方式是什么(除非是这样
Edit:要成为一个“更好”的解决方案,它的性能必须与嵌套的with mutations
调用一样好或更好。您最好使用为此设计的函数,而不是forEach
和push
var list1 = Immutable.List();
var list2 = Immutable.List();
var names = list.map(function(item) { return item.get("name") })
var ages = list.map(function(item) { return item.get("age") })
list1 = list1.concat(names)
list2 = list2.concat(ages)
在性能测试中,这比任何其他选项都要快。它还具有更接近Immutable.js鼓励的函数式编程模型的优点
为什么不能对每个对象分别执行和突变操作呢?因为这样我就需要对某个东西
进行两次迭代,这可能比用旧方法重置引用效率更低。对某个东西进行两次迭代不会让你做更多的工作。如果您迭代两次并在每次迭代中做一些工作,那么这与迭代一次并在每次迭代中做两倍的工作是相同的。唯一的开销是重置循环计数器,这是非常小的。这意味着必须访问列表中的每个元素两次。这就是工作,尤其是在列表很大的情况下。访问列表中的元素是一个常数时间(对于任何合适的语言来说,常数非常小)。你真的认为你会被JS中数组索引的速度所束缚吗?如果我们正在映射的东西(在我的原始示例中,list
在你的示例中)是一个映射会发生什么?我想创建两个列表。由于.map()
返回的类型与映射的对象相似,因此我必须先将这两个映射,名称
和年龄
转换为列表,然后才能将它们合并,对吗?这就是我目前使用.forEach()
的原因。我跑了,它的表现更糟。有没有更好的转换方法?我非常喜欢你简单的方法。