Immutable - change elements in array with slice (no splice)
Asked Answered
V

6

20

How is possible to change 3/4 elements? Expected output is [1,2,4,3,5]

let list = [1,2,3,4,5];
const removeElement = list.indexOf(3); // remove number 3
list.slice(0, removeElement).concat(list.slice(removeElement+1)) // [1,2,4,5]

...next push number 3 after number 4 without splice

Vesper answered 22/11, 2016 at 8:56 Comment(5)
But why without splice? Splice is designed for this purpose...Aedes
@Aedes Array.prototype.splice() is not immutable. It modifies the given array. Looks like OP is looking for an immutable solution.Employee
@Employee I could swear that the question was not phrased that way when i wrote that comment, could be wrong though. slice().splice() works though, for immutabilityAedes
slice().splice() (copying and then using splice) doesn't work because splice returns the removed elements, not the updated arrayLandaulet
just trow the new array created in the last row into some varEfrainefram
P
30

slice doesn't mutate the array on which it operates so you need to assign a value to what it returns

let list = [1,2,3,4,5];
const removeElement = list.indexOf(3); // remove number 3
var newList = list.slice(0, removeElement).concat(list.slice(removeElement+1)) // [1,2,4,5]

If you are prepared to use ES2015 syntax, you can use the spread operator as follows:

const removeElement = list.indexOf(3); // remove number 3
var es6List = [
  ...list.slice(0, removeElement),
  ...list.slice(removeElement+1)
];
console.log(es6List);

fiddle

Plead answered 22/11, 2016 at 9:2 Comment(1)
Note that this doesn't strictly answer the question as it's missing the final part that pushes 3 after 4.Seaver
C
11

The simplest way to write this is to use the spread operator:

let newList = [...list.slice(0, 2), list[3], list[2], ...list.slice(4)];
Campeche answered 22/11, 2016 at 9:3 Comment(1)
Edit queue is full but there's an off-by-one error here (should be list[3], list[2] to generate [1,2,4,3,5])Commensal
H
4

The easer solution might be using filter instead of splice or slice. According to documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

It means the original array stays immutable. The only difference is that in this case, you have to know the value you want to delete instead of index.

let list = [1,2,3,4,5];
list.filter((item) => item !== 3);
Holding answered 19/11, 2019 at 11:2 Comment(1)
This gets rid of the 3, but you need to inject it back into the array after the 4. That's where you need the splice.Seaver
B
3
var list = [1,2,3,4,5];
var numToRemove = 3;

var removeElementIndex = list.indexOf(numToRemove);
var afterRemoveElement = list[removeElementIndex+1];

list.slice(0, removeElementIndex).concat(afterRemoveElement).concat(numToRemove).concat(list.slice(removeElementIndex+2)) // [1,2,4,3,5]
Beater answered 22/11, 2016 at 9:3 Comment(0)
K
3

Object.assign actually works here

const newList = Object.assign([], list, {
  2: list[3],
  3: list[2],
});

list // [1,2,3,4,5]
newList // [1,2,4,3,5]
newList === list // false
Kinnikinnick answered 29/8, 2019 at 9:52 Comment(0)
G
-2

Arrays are objects, use Object.assign() and access elements with property name expressions.

var numToMove = 2;
console.log(Object.assign(list, {[numToMove]: list[numToMove+1]}, 
{[numToMove+1]: list[numToMove]}));
// [1, 2, 4, 3, 5]
Gustafson answered 3/3, 2018 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.