Javascript 在一行代码中用扩展语法替换数组项?
我正在使用。。。扩展语法。这项工作:Javascript 在一行代码中用扩展语法替换数组项?,javascript,reactjs,spread-syntax,Javascript,Reactjs,Spread Syntax,我正在使用。。。扩展语法。这项工作: let newImages = [...this.state.images] newImages[4] = updatedImage this.setState({images:newImages}) 是否可以在一行代码中完成此操作?像这样的?(这显然不起作用……) 该工作是否: this.setState({images: Object.assign([], this.state.images, {4: updatedImage})); …但涉及一个临
let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})
是否可以在一行代码中完成此操作?像这样的?(这显然不起作用……)
该工作是否:
this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));
…但涉及一个临时对象(末尾的对象)。不过,只有一个临时对象。。。如果您使用slice
并展开数组来执行此操作,那么它将涉及多个临时对象(来自slice
的两个数组、它们的迭代器、通过调用迭代器的next
函数[在..
句柄内]创建的结果对象等)
它之所以有效是因为1(当然这需要优化),它们是具有一些特殊特性的对象。它们的“索引”实际上是属性名2。因此,我们将this.state.images
展开到一个新数组中,将其传递到对象中。将指定为目标,并将对象指定为一个名为“4”
属性的对象(是的,它最终是一个字符串,但允许我们将其作为数字写入),并使用我们要更新的值
实例:
const a=[0,1,2,3,4,5,6,7];
const b=Object.assign([],a,{4:“four”});
控制台日志(b)代码>您可以使用地图:
const newImages = this.state.images
.map((image, index) => index === 4 ? updatedImage : image)
使用
这是我自我解释的非一行
const wantedIndex = 4;
const oldArray = state.posts; // example
const updated = {
...oldArray[wantedIndex],
read: !oldArray[wantedIndex].read // attributes to change...
}
const before = oldArray.slice(0, wantedIndex);
const after = oldArray.slice(wantedIndex + 1);
const menu = [
...before,
updated,
...after
]
我参考了@Bardia Rastin solution,发现该解决方案在索引值处有一个错误(它替换了索引3处的项,而不是索引4处的项)
如果要替换具有索引值index的项,则答案应为
this.setState({images:[…this.state.images.slice(0,索引),updateImage,…this.state.images.slice(索引+1)])
this.state.images.slice(0,索引)
是一个新数组,其项从0开始到索引-1(不包括索引)
this.state.images.slice(index)
是一个新的数组,它的项从索引开始,然后是
要正确替换索引4中的项目,答案应为:
this.setState({images:[…this.state.images.slice(0,4),updateImage,…this.state.images.slice(5)])
您可以将数组转换为对象(数组1
),替换项(数组[1]:“七”
),然后将其转换回数组(对象。值
):
array1=[“一”、“二”、“三”];
array2=Object.values({…array1[1]:“seven”});
控制台日志(array1);
控制台日志(array2)
这个答案显示了对…spread运算符的最佳理解,并且它没有使用任何其他奇特的秘密javascript魔法,因此我将把这个标记为答案。当索引未知时,您将如何执行此操作?如果n=0,则得到n-1的切片(0,-1)。是否有一个优雅的方法?请为未知索引提供一个更通用的解决方案。如果索引未知,您必须开始搜索,并且尝试在一行中进行搜索很少是一个好主意。你会有一行很长的,不太可读。为什么不写一个helper函数来获取索引,然后使用这个代码段呢?如果想替换索引4中的项目,这个答案是不正确的,请参考我的答案以获得进一步的解释。真的很好的答案!但正如你所说,这有点折磨人,使代码有点unreadable@Kokodoko:但比分散两个临时数组更有效。:-)也许我不应该首先使用数组,完全避免这种复杂性?如果我使用一个变量而不是像这样的数字,它会工作吗?@vuquanghoang:是的,如果使用计算属性名。:-)我已经更新了答案来说明这一点,好建议!嗯,是的,但是如果我的数组有1000个条目,每次我想更新一个条目时,我都必须映射它们。@Kokodoko我认为在这种情况下,这会更快。我可能遗漏了一些东西,但是看看这里:谢谢你构建这个测试,太棒了!当我运行它时,似乎Object.assign速度最快,为168.000次/秒,紧随其后的是spread,为146.000次/秒。地图是目前速度最慢的,每秒只有27.000次。我用Chrome 60得到了完全不同的结果:speard-13149,地图-31702,Object.assign-12744。你说得对!这很奇怪。我测试了Chrome和Safari。在Chrome上,map
比Safari快得多。在Safari上,spread
和assign
的速度几乎是Chrome上的10倍!这是一个很好的例子,但是在将数组转换为对象并返回时是否存在效率问题?
this.setState({images: [...this.state.images.slice(0, 3), updatedImage, ...this.state.images.slice(4)]})
const wantedIndex = 4;
const oldArray = state.posts; // example
const updated = {
...oldArray[wantedIndex],
read: !oldArray[wantedIndex].read // attributes to change...
}
const before = oldArray.slice(0, wantedIndex);
const after = oldArray.slice(wantedIndex + 1);
const menu = [
...before,
updated,
...after
]