12225

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.

2
  • @GustavoGonçalves yes. arrays should have a remove method and if anyone says "what about if the developer added it already?" then make it a weak add. If the remove member/function does not exist on the array then add it. Array needs it. Commented Dec 6, 2023 at 2:57
  • 5
    @1.21gigawatts that doesn't work because the custom remove method can have different signature or semantics from one added later. Therefore 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 and Array#contains. This literally had an effect of the whole of the internet because contains was removed to includes to avoid that clash. Commented Dec 6, 2023 at 6:36

51 Answers 51

1
2
12

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...)

Sign up to request clarification or add additional context in comments.

Comments

11

Remove one value, using loose comparison, without mutating the original array, ES6

/**
 * 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;
}

3 Comments

export const arrayRemove = (array, value) => [...array.filter(item => item !== value)]; Perhaps this could be simpler.
@darmis Simpler, yes, but doesn't do exactly the same thing. Also don't think you need the [... -- .filter should already return a copy.
@mpem My first impression was that could be a simpler way to do this but I agree is not doing the same thing. And yes the [... it is not needed in this case so even simpler :) thanks for that.
11

Most of the answers here give a solution using -

  1. indexOf and splice
  2. delete
  3. filter
  4. regular for loop

Although all the solutions should work with these methods, I thought we could use string manipulation.

Points to note about this solution -

  1. It will leave holes in the data (they could be removed with an extra filter)
  2. This solution works for not just primitive search values, but also objects.

The trick is to -

  1. stringify input data set and the search value
  2. replace the search value in the input data set with an empty string
  3. return split 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.

2 Comments

So, what exactly is the advantage of this method? What I see is that it's a terribly inefficient and error-prone method of performing a simple task. The result is not parsed again so it returns an array of strings instead of the input type. Even if it was parsed, on arrays of objects it would remove all function members. I don't see any good reason to ever do something like that but given that there are two people who thought this was a good idea, there must be something I'm missing.
I agree with @StefanFabian, this is a terrible idea. What if my string is something like ",", that will replace all commas in the string version of the array. This is a terrible idea, and you should not do this.
11

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();
}

Comments

11

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);

1 Comment

What is the advantage of that?
11

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);

3 Comments

The first solution can be dangerous, as, if the element is not found, the last element of the array will be removed. This is because, when the element is not found, .indexOf will return -1 and using .splice(-1, 1) removes the last element.
that doesn't matter. simple and ez answer.
Why are you using != instead of !==?
11

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.

Comments

10

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>

1 Comment

The OP specifically said no frameworks. Hence the downvote.
10

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;
}

2 Comments

All of these options are overcomplicated and inefficient.
They were okay 8 years ago. Here's a simple one for today const remove = (array, item) => array.filter(x => x !== item);
7

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>

2 Comments

What is meaning of this code I could not understand.
@AnkurLoriya This code removes all 0s from the given array
7

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;

Comments

7

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:

  1. In case you want to delete just last element, you can use Array.pop()

  2. In case you want to delete just first element, you can use Array.shift()

  3. 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);
        }
    }
    
  4. 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]
    

2 Comments

Note: Array.prototype.filter is ECMAScript 5.1 (No IE8)
For option 4, should the loop be 'i < arr.length' not 'i < arr.length-1'?
6
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.

1 Comment

This is very inefficient when the array is large.
4

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.

Comments

3

Lodash:

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])

Comments

2
Array.prototype.remove = function(x) {
    var y=this.slice(x+1);
    var z=[];
    for(i=0;i<=x-1;i++) {
        z[z.length] = this[i];
    }

    for(i=0;i<y.length;i++){
        z[z.length]=y[i];
    }

    return z;
}

Comments

2

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);

3 Comments

You can see that there are strings in the second example I provided? I am not sure what you mean by this? The only issue is if your string contains one of the charterers used in the separation, as I mentioned in my answer.
Interesting method, you can use Unicode characters for splitting (e.g. '\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).
No one has done it with a one-liner… except the #2 answer. And that one actually worked for the first and last elements, arbitrary strings, things that aren’t stringifiable at all, ….
2

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.

1 Comment

This is comically worse than (the equally functional) filter.
2

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);

Comments

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]

Comments

-2

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;
}

1 Comment

I'm not sure this answer provides much over this one: stackoverflow.com/a/5767335 or this one: stackoverflow.com/a/15762329 Also, as a warning: you are globally defining i.
1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.