Reputation: 17334
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.
Upvotes: 79
Views: 88501
Reputation: 121
If you wanted a utility to reuse :
const myArray = ["one", "two", "three", "four", "five"];
const yourSplice = (yourArray, elementToRemove) => {
const index = yourArray.indexOf(elementToRemove);
if (index !== -1) {
return [...yourArray.slice(0, index), ...yourArray.slice(index+1)];
}
return yourArray;
}
console.log(yourSplice(myArray, "three"));
Upvotes: 0
Reputation: 7296
Return new array without mutating original one
JavaScript arrays has a new method for this purpose: array.toSpliced()
const months = ["Jan", "Mar", "Apr", "May"];
//Delete at index 1
const months1 = months.toSpliced(1,1);
console.log(months1); // ["Jan", "Apr", "May"]
// Deleting/Inserting an element at index 1
const months2 = months.toSpliced(1, 0, "Feb");
console.log(months2); // ["Jan", "Feb", "Mar", "Apr", "May"]
//months remain unchanged ["Jan", "Mar", "Apr", "May"]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSpliced
Upvotes: 1
Reputation: 2694
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
.
Upvotes: 6
Reputation: 46
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"]
Upvotes: 3
Reputation: 7675
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.
Upvotes: 6
Reputation: 2343
document.write(myArray.filter(e => e !== "two"));
document.write(myArray);
Upvotes: 0
Reputation: 16440
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);
Upvotes: 59
Reputation: 26548
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));
Upvotes: 0
Reputation: 13270
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
Upvotes: 0
Reputation: 320
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"]
Upvotes: 2
Reputation: 1014
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']
Upvotes: 6
Reputation: 291
Use this:
function spliceNoMutate(myArray,indexToRemove) {
return myArray.slice(0,indexToRemove).concat(myArray.slice(indexToRemove+1));
}
Upvotes: 29
Reputation: 577
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".
Upvotes: 14
Reputation: 434665
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 includingend
.
Upvotes: 50
Reputation: 77966
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/
Upvotes: 0