Returning an array without a removed element? Using splice() without changing the array?

JavascriptArrays

Javascript Problem Overview


I want to do something like:

var myArray = ["one","two","three"];
document.write(myArray.splice(1,1));
document.write(myArray);

So that it shows first "one,three", and then "one,two,three". I know splice() returns the removed element and changes the array, but is there function to return a new array with the element removed? I tried:

window.mysplice = function(arr,index,howmany){
    arr.splice(index,howmany);
    return arr;   
};

If I try:

var myArray = ["one","two","three"];
document.write(mySplice(myArray,1,1));
document.write(myArray);

It still changes myArray.

Javascript Solutions


Solution 1 - Javascript

You want slice:

> Returns a one-level deep copy of a portion of an array.

So if you

a = ['one', 'two', 'three' ];
b = a.slice(1, 3);

Then a will still be ['one', 'two', 'three'] and b will be ['two', 'three']. Take care with the second argument to slice though, it is one more than the last index that you want to slice out:

> Zero-based index at which to end extraction. slice extracts up to but not including end.

Solution 2 - Javascript

as suggested by the answer below, here is a code snapshot

var myArray = ["one", "two", "three"];
var cloneArray = myArray.slice();

myArray.splice(1, 1);

console.log(myArray);
console.log(cloneArray);

Solution 3 - Javascript

Use this:

function spliceNoMutate(myArray,indexToRemove) {
    return myArray.slice(0,indexToRemove).concat(myArray.slice(indexToRemove+1));
}

Solution 4 - Javascript

I know this question is old, but this approach might come in handy.

var myArray = ["one","two","three"];
document.write(myArray.filter(function(v, index) { return index !== 1 })

or

var myArray = ["one","two","three"];
document.write(myArray.filter(function(v, index) { return v !== "two" })

This uses the Array.filter() function and tests against either the index being 1 or the value being "two".


Now, I cannot vouch for these solution's performance (as it checks each item on the array, Nguyen's answer might be more efficient), but it is more flexible if you want to do more complicated stuff and sure is easier to understand.

Solution 5 - Javascript

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

const oneTwoThree = ['one', 'two', 'three'] // original array

// `filter()` (like most array functions) iterates over every item in the array.
// Whatever returns true here is copied to a new array (the `oneThree` variable).
// `item !== 'two'` returns true for everything except 'two'
const oneThree = oneTwoThree.filter(item => item !== 'two')

console.log(oneTwoThree) // ['one', 'two', 'three'] — the original, unscathed, array
console.log(oneThree) // ['one', 'three'] — a copy of the original, sans the value you wanted to remove

You'd want to do this so you have a non-mutated array.

> I don't think performance is as good as something like slice + concat, but worry about that if it becomes a problem (it probably won't unless you're dealing with tens-of-thousands of elements in an array). Until then, filter is really clean.

> Also note that this will remove ALL instances of the element two from the array, so make sure you don't have duplicates in your array that might unintentionally get gobbled up by this approach.

Solution 6 - Javascript

You can use the ES6 spread feature:

let myArray = ['one','two','three'];
let mySplicedArray = [...myArray];
mySplicedArray.splice(1,1); 

console.log(myArray); /// ['one', 'two', 'three']
console.log(mySplicedArray); /// ['one', 'three']

Solution 7 - Javascript

I think the best approach to splice an element from array without mutating and without making a copy of itself is using filter:

arr = ["one", "two", "three"]
elToRemove = "two"
filteredArr = arr.filter( n => n != elToRemove)

console.log(arr) // ["one", "two", "three"]
console.log(filteredArr) // ["one", "three"]

Solution 8 - Javascript

If you have the index of the element you want to remove, you can use slice() and spread syntax:

let fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
let removeIndex = 2;
let iHateLemons = [...fruits.slice(0, removeIndex), ...fruits.slice(removeIndex+1)]

// your new array
// console.log(iHateLemons) --> ["Banana", "Orange", "Apple", "Mango"]
// original array still intact
// console.log(fruits) --> ["Banana", "Orange", "Lemon", "Apple", "Mango"]

Solution 9 - Javascript

There's a new tc39 proposal, which adds a toSpliced method to Array that returns a copy of the array and doesn't modify the original.

When this is implemented, the question can be answered with:

const myArray = ["one", "two", "three"];
myArray.toSpliced(1, 1); // => ["one", "three"]
myArray; // => ["one", "two", "three"];

As it's currently in stage 3, it will likely be implemented in browser engines soon, but in the meantime a polyfill is available here or in core-js.

Solution 10 - Javascript

Instead of this:

document.write(myArray.splice(1,1));

why not just use:

document.write(myArray[1]);

splice() modifies the array in place by definition. See slice() if you want a copy.

Solution 11 - Javascript

Why not just reference the index?

var myArray = ["one","two","three"];
document.write(myArray[1] + '<br />');
document.write(myArray);

Example: http://jsfiddle.net/AlienWebguy/dHTUj/

Solution 12 - Javascript

I think the neatest way is to create a simple function, and bind the function to the Array prototype if you need global access.

Most of the answers provided to the question are wrong. People confuse returning one element of one array without modifying its content but what the OP needs is to return a clone of the array without one element.

Here's my solution :

let arr = ['one', 'two', 'three'];

/* functional */
window.cloneSlice = (arr, start, end) => {
  const _arr = arr.slice();
  _arr.splice(start, end);
  return _arr;
}
// usage
console.log(cloneSlice(arr, 1, 1)); // one, three
console.log(arr); // one, two, three

/* prototyped */
Array.prototype.cloneSlice = function (start, end) { return cloneSlice(this, start, end) }
// usage
console.log(arr.cloneSlice(1, 1)); // one, three
console.log(arr); // one, two, three

Solution 13 - Javascript

const getSubArr = (arr, start, end) => {
    return end > start
        ? arr.filter((_, i) => i >= start && i < end)
        : arr.filter((_, i) => i >= start || i < end);
};

This function returns an array which is a sequence of the original array. It's advantage is that it could be used to get a subArray without a sequence located in the middle of the original array.

const chars = ["a", "b", "c", "d", "e", "f"];
console.log(getArrInRange(chars, 2, 4));
console.log(getArrInRange(chars, 4, 2));

Solution 14 - Javascript

document.write(myArray.filter(e => e !== "two"));
document.write(myArray);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmowwwalkerView Question on Stackoverflow
Solution 1 - Javascriptmu is too shortView Answer on Stackoverflow
Solution 2 - JavascriptNevereverView Answer on Stackoverflow
Solution 3 - JavascriptThai-Duong NguyenView Answer on Stackoverflow
Solution 4 - JavascriptRafaelView Answer on Stackoverflow
Solution 5 - JavascriptcorysimmonsView Answer on Stackoverflow
Solution 6 - JavascriptarthurDentView Answer on Stackoverflow
Solution 7 - JavascriptEl PaneView Answer on Stackoverflow
Solution 8 - JavascriptmjclView Answer on Stackoverflow
Solution 9 - JavascriptJoshView Answer on Stackoverflow
Solution 10 - Javascriptjfriend00View Answer on Stackoverflow
Solution 11 - JavascriptAlienWebguyView Answer on Stackoverflow
Solution 12 - JavascriptvdegenneView Answer on Stackoverflow
Solution 13 - JavascriptBen CarpView Answer on Stackoverflow
Solution 14 - JavascriptYorkshiremanView Answer on Stackoverflow