How do I remove a specific value from an array? Something like:
array.remove(value);
Constraints: I have to use core JavaScript. Frameworks are not allowed.
What a shame you have an array of integers, not an object where the keys are string equivalents of these integers.
I've looked through a lot of these answers and they all seem to use "brute force" as far as I can see. I haven't examined every single one, apologies if this is not so. For a smallish array this is fine, but what if you have 000s of integers in it?
Correct me if I'm wrong, but can't we assume that in a key => value map, of the kind which a JavaScript object is, that the key retrieval mechanism can be assumed to be highly engineered and optimised? (NB: if some super-expert tells me that this is not the case, I can suggest using ECMAScript 6's Map class instead, which certainly will be).
I'm just suggesting that, in certain circumstances, the best solution might be to convert your array to an object... the problem being, of course, that you might have repeating integer values. I suggest putting those in buckets as the "value" part of the key => value entries. (NB: if you are sure you don't have any repeating array elements this can be much simpler: values "same as" keys, and just go Object.values(...) to get back your modified array).
So you could do:
const arr = [ 1, 2, 55, 3, 2, 4, 55 ];
const f = function( acc, val, currIndex ){
// We have not seen this value before: make a bucket... NB: although val's typeof is 'number',
// there is seamless equivalence between the object key (always string)
// and this variable val.
! ( val in acc ) ? acc[ val ] = []: 0;
// Drop another array index in the bucket
acc[ val ].push( currIndex );
return acc;
}
const myIntsMapObj = arr.reduce( f, {});
console.log( myIntsMapObj );
Output:
Object [ <1 empty slot>, Array1, Array[2], Array1, Array1, <5 empty slots>, 46 more… ]
It is then easy to delete all the numbers 55.
delete myIntsMapObj[ 55 ]; // Again, although keys are strings this works
You don't have to delete them all: index values are pushed into their buckets in order of appearance, so (for example):
myIntsMapObj[ 55 ].shift(); // And
myIntsMapObj[ 55 ].pop();
will delete the first and last occurrence respectively. You can count frequency of occurrence easily, replace all 55s with 3s by transferring the contents of one bucket to another, etc.
Retrieving a modified int array from your "bucket object" is slightly involved but not so much: each bucket contains the index (in the original array) of the value represented by the (string) key. Each of these bucket values is also unique (each is the unique index value in the original array): so you turn them into keys in a new object, with the (real) integer from the "integer string key" as value... then sort the keys and go Object.values( ... ).
This sounds very involved and time-consuming... but obviously everything depends on the circumstances and desired usage. My understanding is that all versions and contexts of JavaScript operate only in one thread, and the thread doesn't "let go", so there could be some horrible congestion with a "brute force" method: caused not so much by the indexOf ops, but multiple repeated slice/splice ops.
Addendum If you're sure this is too much engineering for your use case surely the simplest "brute force" approach is
const arr = [ 1, 2, 3, 66, 8, 2, 3, 2 ];
const newArray = arr.filter( number => number !== 3 );
console.log( newArray )
(Yes, other answers have spotted Array.prototype.filter...)
/**
* Removes one instance of `value` from `array`, without mutating the original array. Uses loose comparison.
*
* @param {Array} array Array to remove value from
* @param {*} value Value to remove
* @returns {Array} Array with `value` removed
*/
export function arrayRemove(array, value) {
for(let i=0; i<array.length; ++i) {
if(array[i] == value) {
let copy = [...array];
copy.splice(i, 1);
return copy;
}
}
return array;
}
export const arrayRemove = (array, value) => [...array.filter(item => item !== value)]; Perhaps this could be simpler.[... -- .filter should already return a copy.[... it is not needed in this case so even simpler :) thanks for that.Most of the answers here give a solution using -
for loopAlthough all the solutions should work with these methods, I thought we could use string manipulation.
Points to note about this solution -
The trick is to -
stringify input data set and the search valuesplit data on delimiter ,. remove = (input, value) => {
const stringVal = JSON.stringify(value);
const result = JSON.stringify(input)
return result.replace(stringVal, "").split(",");
}
A JSFiddle with tests for objects and numbers is created here - https://jsfiddle.net/4t7zhkce/33/
Check the remove method in the fiddle.
I post my code that removes an array element in place, and reduce the array length as well.
function removeElement(idx, arr) {
// Check the index value
if (idx < 0 || idx >= arr.length) {
return;
}
// Shift the elements
for (var i = idx; i > 0; --i) {
arr[i] = arr[i - 1];
}
// Remove the first element in array
arr.shift();
}
Non in-place solution
arr.slice(0,i).concat(arr.slice(i+1));
let arr = [10, 20, 30, 40, 50]
let i = 2 ; // position to remove (starting from 0)
let r = arr.slice(0,i).concat(arr.slice(i+1));
console.log(r);
For removing only the first 34 from ages, not all the ages 34:
ages.splice(ages.indexOf(34), 1);
Or you can define a method globally:
function remove(array, item){
let ind = array.indexOf(item);
if(ind !== -1)
array.splice(ind, 1);
}
For removing all the ages 34:
ages = ages.filter(a => a !== 34);
.indexOf will return -1 and using .splice(-1, 1) removes the last element.!= instead of !==?The best way to remove an item from an array is to use the filter method.
.filter() returns a new array without the filtered items.
items = items.filter(e => e.id !== item.id);
This .filter() method maps to a complete array and when I return the true condition, it pushes that current item to the filtered array.
Read more on filter here.
Use jQuery.grep():
var y = [1, 2, 3, 9, 4]
var removeItem = 9;
y = jQuery.grep(y, function(value) {
return value != removeItem;
});
console.log(y)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
Vanilla JavaScript (ES5.1) – in place edition
Browser support: Internet Explorer 9 or later (detailed browser support)
/**
* Removes all occurences of the item from the array.
*
* Modifies the array “in place”, i.e. the array passed as an argument
* is modified as opposed to creating a new array. Also returns the modified
* array for your convenience.
*/
function removeInPlace(array, item) {
var foundIndex, fromIndex;
// Look for the item (the item can have multiple indices)
fromIndex = array.length - 1;
foundIndex = array.lastIndexOf(item, fromIndex);
while (foundIndex !== -1) {
// Remove the item (in place)
array.splice(foundIndex, 1);
// Bookkeeping
fromIndex = foundIndex - 1;
foundIndex = array.lastIndexOf(item, fromIndex);
}
// Return the modified array
return array;
}
Vanilla JavaScript (ES5.1) – immutable edition
Browser support: Same as vanilla JavaScript in place edition
/**
* Removes all occurences of the item from the array.
*
* Returns a new array with all the items of the original array except
* the specified item.
*/
function remove(array, item) {
var arrayCopy;
arrayCopy = array.slice();
return removeInPlace(arrayCopy, item);
}
Vanilla ES6 – immutable edition
Browser support: Chrome 46, Edge 12, Firefox 16, Opera 37, Safari 8 (detailed browser support)
/**
* Removes all occurences of the item from the array.
*
* Returns a new array with all the items of the original array except
* the specified item.
*/
function remove(array, item) {
// Copy the array
array = [...array];
// Look for the item (the item can have multiple indices)
let fromIndex = array.length - 1;
let foundIndex = array.lastIndexOf(item, fromIndex);
while (foundIndex !== -1) {
// Remove the item by generating a new array without it
array = [
...array.slice(0, foundIndex),
...array.slice(foundIndex + 1),
];
// Bookkeeping
fromIndex = foundIndex - 1;
foundIndex = array.lastIndexOf(item, fromIndex)
}
// Return the new array
return array;
}
const remove = (array, item) => array.filter(x => x !== item);The following method will remove all entries of a given value from an array without creating a new array and with only one iteration which is superfast. And it works in ancient Internet Explorer 5.5 browser:
function removeFromArray(arr, removeValue) {
for (var i = 0, k = 0, len = arr.length >>> 0; i < len; i++) {
if (k > 0)
arr[i - k] = arr[i];
if (arr[i] === removeValue)
k++;
}
for (; k--;)
arr.pop();
}
var a = [0, 1, 0, 2, 0, 3];
document.getElementById('code').innerHTML =
'Initial array [' + a.join(', ') + ']';
//Initial array [0, 1, 0, 2, 0, 3]
removeFromArray(a, 0);
document.getElementById('code').innerHTML +=
'<br>Resulting array [' + a.join(', ') + ']';
//Resulting array [1, 2, 3]
<code id="code"></code>
There are many fantastic answers here, but for me, what worked most simply wasn't removing my element from the array completely, but simply setting the value of it to null.
This works for most cases I have and is a good solution since I will be using the variable later and don't want it gone, just empty for now. Also, this approach is completely cross-browser compatible.
array.key = null;
To remove a particular element or subsequent elements, Array.splice() method works well.
The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements, and it returns the removed item(s).
Syntax: array.splice(index, deleteCount, item1, ....., itemX)
Here index is mandatory and rest arguments are optional.
For example:
let arr = [1, 2, 3, 4, 5, 6];
arr.splice(2,1);
console.log(arr);
// [1, 2, 4, 5, 6]
Note: Array.splice() method can be used if you know the index of the element which you want to delete. But we may have a few more cases as mentioned below:
In case you want to delete just last element, you can use Array.pop()
In case you want to delete just first element, you can use Array.shift()
If you know the element alone, but not the position (or index) of the element, and want to delete all matching elements using Array.filter() method:
let arr = [1, 2, 1, 3, 4, 1, 5, 1];
let newArr = arr.filter(function(val){
return val !== 1;
});
//newArr => [2, 3, 4, 5]
Or by using the splice() method as:
let arr = [1, 11, 2, 11, 3, 4, 5, 11, 6, 11];
for (let i = 0; i < arr.length-1; i++) {
if ( arr[i] === 11) {
arr.splice(i, 1);
}
}
console.log(arr);
// [1, 2, 3, 4, 5, 6]
Or suppose we want to delete del from the array arr:
let arr = [1, 2, 3, 4, 5, 6];
let del = 4;
if (arr.indexOf(4) >= 0) {
arr.splice(arr.indexOf(4), 1)
}
Or
let del = 4;
for(var i = arr.length - 1; i >= 0; i--) {
if(arr[i] === del) {
arr.splice(i, 1);
}
}
If you know the element alone but not the position (or index) of the element, and want to delete just very first matching element using splice() method:
let arr = [1, 11, 2, 11, 3, 4, 5, 11, 6, 11];
for (let i = 0; i < arr.length-1; i++) {
if ( arr[i] === 11) {
arr.splice(i, 1);
break;
}
}
console.log(arr);
// [1, 11, 2, 11, 3, 4, 5, 11, 6, 11]
var index,
input = [1,2,3],
indexToRemove = 1;
integers = [];
for (index in input) {
if (input.hasOwnProperty(index)) {
if (index !== indexToRemove) {
integers.push(result);
}
}
}
input = integers;
This solution will take an array of input and will search through the input for the value to remove. This will loop through the entire input array and the result will be a second array integers that has had the specific index removed. The integers array is then copied back into the input array.
I would like to suggest to remove one array item using delete and filter:
var arr = [1,2,3,4,5,5,6,7,8,9];
delete arr[5];
arr = arr.filter(function(item){ return item != undefined; });
//result: [1,2,3,4,5,6,7,8,9]
console.log(arr)
So, we can remove only one specific array item instead of all items with the same value.
let a1 = {name:'a1'}
let a2 = {name:'a2'}
let a3 = {name:'a3'}
let list = [a1, a2, a3]
_.remove(list, a2)
//list now is [{name: "a1"}, {name: "a3"}]
Check this for details: .remove(array, [predicate=.identity])
There are already a lot of answers, but because no one has done it with a one liner yet, I figured I'd show my method. It takes advantage of the fact that the string.split() function will remove all of the specified characters when creating an array. Here is an example:
var ary = [1,2,3,4,1234,10,4,5,7,3];
out = ary.join("-").split("-4-").join("-").split("-");
console.log(out);
In this example, all of the 4's are being removed from the array ary. However, it is important to note that any array containing the character "-" will cause issues with this example. In short, it will cause the join("-") function to piece your string together improperly. In such a situation, all of the the "-" strings in the above snipet can be replaced with any string that will not be used in the original array. Here is another example:
var ary = [1,2,3,4,'-',1234,10,'-',4,5,7,3];
out = ary.join("!@#").split("!@#4!@#").join("!@#").split("!@#");
console.log(out);
'\uD842') instead. For making it clearer and shorter for others, I'd just add a few more strings to the array elements (including '4') and take out the first snippet/example (people may have downvoted because they didn't even read the 2nd part).Take profit of reduce method as follows:
Case a) if you need to remove an element by index:
function remove(arr, index) {
return arr.reduce((prev, x, i) => prev.concat(i !== index ? [x] : []), []);
}
case b) if you need to remove an element by the value of the element (int):
function remove(arr, value) {
return arr.reduce((prev, x, i) => prev.concat(x !== value ? [x] : []), []);
}
So in this way we can return a new array (will be in a cool functional way - much better than using push or splice) with the element removed.
filter.If you want to create a new array instead of modifying the original array in place, use Array.prototype.toSpliced():
const index = array.indexOf(value);
const newArray = array.toSpliced(index, 1);
Beside all this solutions it can also be done with array.reduce...
const removeItem =
idx =>
arr =>
arr.reduce((acc, a, i) => idx === i ? acc : acc.concat(a), [])
const array = [1, 2, 3]
const index = 1
const newArray = removeItem(index)(array)
console.log(newArray) // logs the following array to the console : [1, 3]
... or a recursive function (which is to be honest not that elegant...has maybe someone a better recursive solution ??)...
const removeItemPrep =
acc =>
i =>
idx =>
arr =>
// If the index equals i, just feed in the unchanged accumulator(acc) else...
i === idx ? removeItemPrep(acc)(i + 1)(idx)(arr) :
// If the array length + 1 of the accumulator is smaller than the array length of the original array concatenate the array element at index i else...
acc.length + 1 < arr.length ? removeItemPrep(acc.concat(arr[i]))(i + 1)(idx)(arr) :
// return the accumulator
acc
const removeItem = removeItemPrep([])(0)
const array = [1, 2, 3]
const index = 1
const newArray = removeItem(index)(array)
console.log(newArray) // logs the following array to the console : [1, 3]
If you are restricted to ExtendScript as Adobe InDesign scripter, then you could use the following function. Please keep in mind that InDesign has only ExtendScript dd. from the late 1990s incorporated where many "modern" JavaScript function aren't available - so the vast majority of the suggested solutions above won't work in InDesign, unfortunately. Also keep in mind that really "global"/"local" variables were not part of ES at this time.
function removeItemOnce(arr, value) {
for ( i in arr ) {
if ( arr[i] == value ) {
arr = arr.splice(i, 1);
break;
}
}
return arr;
}
i.
removemember/function does not exist on the array then add it. Array needs it.arr.remove(foo)can start to behave differently if it's later added to arrays and your custom method addition yields to that implementation. And that's not even a hypothetical, it's something that happens with MooTools andArray#contains. This literally had an effect of the whole of the internet becausecontainswas removed toincludesto avoid that clash.