19

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

Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
Ingrid Oberbüchler
  • 766
  • 2
  • 6
  • 16
  • But why without splice? Splice is designed for this purpose... – Dellirium Nov 22 '16 at 09:13
  • 3
    @Dellirium `Array.prototype.splice()` is not immutable. It modifies the given array. Looks like OP is looking for an immutable solution. – chrisg86 Feb 12 '19 at 18:45
  • 1
    @chrisg86 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 immutability – Dellirium Feb 13 '19 at 13:16
  • 2
    `slice().splice()` (copying and then using splice) doesn't work because splice returns the removed elements, not the updated array – mb7744 Sep 14 '20 at 15:49
  • just trow the new array created in the last row into some var – David Peer Apr 27 '21 at 10:28

6 Answers6

29

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

Mark Williams
  • 2,268
  • 1
  • 11
  • 14
  • Note that this doesn't strictly answer the question as it's missing the final part that pushes 3 after 4. – icc97 Jul 15 '20 at 20:38
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)];
ide
  • 19,942
  • 5
  • 64
  • 106
  • 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]`) – JimmyM Feb 20 '23 at 10:25
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]
Joe
  • 2,500
  • 1
  • 14
  • 12
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
3

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);
Eduard Mukans
  • 857
  • 8
  • 11
  • 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`. – icc97 Jul 15 '20 at 20:41
-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]