Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace array entry with spread syntax in one line of code?

I'm replacing an item in a react state array by using the ... spread syntax. This works:

let newImages = [...this.state.images] newImages[4] = updatedImage this.setState({images:newImages}) 

Would it be possible to do this in one line of code? Something like this? (this doesn't work obviously...)

this.setState({images: [...this.state.images, [4]:updatedImage}) 
like image 520
Kokodoko Avatar asked Aug 14 '17 11:08

Kokodoko


People also ask

How do you update an array of objects using the spread operator?

let array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}]; let array2 = array. map(a => { var returnValue = {...a}; if (a.id == 2) { returnValue.name = "Not Two"; } return returnValue }) console. log(array); console.

How do you spread an array of arrays?

To merge elements from one array to another, we must first iterate(loop) through all the array elements. In the loop, we will retrieve each element from an array and insert(using the array push() method) to another array. Now, we can call the merge() function and pass two arrays as the arguments for merging.

How do you spread an object in an array?

Like the docs say, according to the "Rest/Spread Properties proposal", you can't spread object properties onto an array, objects will always spread their properties onto a new object. Likewise, arrays will not spread onto an object, they will only spread onto a new array.

How do you replace one item in an array?

To replace an element in an array:Use the indexOf() method to get the index of the element you want to replace. Call the Array. splice() method to replace the element at the specific index. The array element will get replaced in place.

Can I copy an array using spread syntax?

Note: Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays, as the following example shows. (The same is true with Object.assign () and spread syntax.) Array.prototype.concat () is often used to concatenate an array to the end of an existing array.

How to use new with array of parameters without spread syntax?

To use new with an array of parameters without spread syntax, you would have to do it indirectly through partial application:

How to use spread operator with array in JavaScript?

Here are 6 ways to use the Spread operator with Array in JavaScript. You can use it to merge or clone an array. Or use it to convert iterables to an array. 1. Use Spread for Merging Array 2. Clone Array 3. String to Array 4. Set to Array 5. Node List to Array 6.

Is it possible to modify an array without spreading it?

You can do it like this in map, no need for spread: Show activity on this post. Show activity on this post. Here the main array also gets modified, as elements inside the array are objects and it references to the same location even in the new array.


2 Answers

use Array.slice

this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]}) 

Edit from original post: changed the 3 o a 4 in the second parameter of the slice method since the second parameter points to the member of the array that is beyond the last one kept, it now correctly answers the original question.

like image 109
Amir Ghezelbash Avatar answered Sep 22 '22 21:09

Amir Ghezelbash


Object.assign does the job:

this.setState({images: Object.assign([], this.state.images, {4: updatedImage})); 

...but involves a temporary object (the one at the end). Still, just the one temp object... If you do this with slice and spreading out arrays, it involve several more temporary objects (the two arrays from slice, the iterators for them, the result objects created by calling the iterator's next function [inside the ... handle], etc.).

It works because normal JS arrays aren't really arrays1(this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2. So there, we're spreading out this.state.images into a new array, passing that into Object.assign as the target, and giving Object.assign an object with a property named "4" (yes, it ends up being a string but we're allowed to write it as a number) with the value we want to update.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];  const b = Object.assign([], a, {4: "four"});  console.log(b);

If the 4 can be variable, that's fine, you can use a computed property name (new in ES2015):

let n = 4; this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage})); 

Note the [] around n.

Live Example:

const a = [0, 1, 2, 3, 4, 5, 6, 7];  const index = 4;  const b = Object.assign([], a, {[index]: "four"});  console.log(b);

1 Disclosure: That's a post on my anemic little blog.

2 It's the second paragraph after the bullet list:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

So that Object.assign does the same thing as your create-the-array-then-update-index-4.

like image 34
T.J. Crowder Avatar answered Sep 22 '22 21:09

T.J. Crowder