56

I have an array like this

arr = ["orange","red","black","white"]

I want to augment the array object defining a deleteElem() method which acts like this:

arr2 = arr.deleteElem("red"); // ["orange","black","white"] (with no hole)

What is the best way to accomplish this task using just the value parameter (no index)?

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
antonjs
  • 14,060
  • 14
  • 65
  • 91
  • This reminds me of .filter(), present in mootools and jquery. Mootools also has, for instance, .erase(), which does just as you ask. There is no reason to reinvent the wheel. – Oliver Sep 05 '11 at 16:25
  • Delete with jQuery http://stackoverflow.com/questions/3596089/how-to-add-and-remove-array-value-in-jquery – itsazzad Jun 17 '13 at 18:34
  • Possible duplicate of [Remove item from array by value](http://stackoverflow.com/questions/3954438/remove-item-from-array-by-value) – Gajus May 01 '17 at 10:10
  • Possible duplicate of [How do I remove a particular element from an array in JavaScript?](https://stackoverflow.com/questions/5767325/how-do-i-remove-a-particular-element-from-an-array-in-javascript) – Heretic Monkey Feb 23 '18 at 20:36

10 Answers10

104

Here's how it's done:

var arr = ["orange","red","black","white"];
var index = arr.indexOf("red");
if (index >= 0) {
  arr.splice( index, 1 );
}

This code will remove 1 occurency of "red" in your Array.

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
  • 6
    Also, you would have to augment your array to support `.indexOf()` which isn't supported in some older versions of IE. – jfriend00 Sep 05 '11 at 16:44
  • 15
    very dangerous, because if "red" is not in an array it deletes "white" – IvanM Apr 18 '14 at 08:50
  • 2
    @IvanMalyshev agreed, this is extremely dangerous. Array.prototype.splice(index, howMany) allows negative index, so you need to check that indexOf does not return -1 (not found) before calling splice. – Dakota Sep 05 '14 at 22:46
  • Really, how can this be the approved answer when i'ts demonstrably wrong, as per the comments by @IvanMalyshev and @Dakota? Downvoted, would upvote with appropriate correction. – enigment Dec 16 '14 at 15:59
  • 1
    Answer has been fixed, upvoted, with the mentioned caveat about .indexOf() compatibility. – enigment Jan 09 '15 at 15:53
  • This doesn't always work for me, e.g. (tested with node repl): `> [1].indexOf(1);` `0` `> [1].splice(0, 1);` `[ 1 ]` – achalk Aug 21 '17 at 22:04
53

Back when I was new to coding I could hardly tell what splice was doing, and even today it feels less readable.

But readability counts.

I would rather use the filter method like so:

arr = ["orange","red","black","white","red"]

arr = arr.filter(val => val !== "red");

console.log(arr) // ["orange","black","white"]

Note how all occurrences of "red" are removed from the array.

From there, you can easily work with more complex data such as array of objects.

arr = arr.filter(obj => obj.prop !== "red");
Romain Vincent
  • 2,875
  • 2
  • 22
  • 29
  • 2
    Looks like it's well-supported: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Browser_compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Browser_compatibility) – ryannjohnson Jan 29 '17 at 01:34
4

There is an underscore method for this, http://underscorejs.org/#without

arr = ["orange","red","black","white"];

arr = _.without(arr, "red");
Ajeesh Joshy
  • 1,387
  • 2
  • 18
  • 32
  • 1
    This solution removes all occurrences of the mentioned value, I was interested in removing only one occurrence of it and keep the duplicates, so in my case this was not a good solution. For example: arr = ["orange", "red", "black", "white", "orange"]; arr = _.without(arr, "orange"); => arr = ["red", "black", "white"] I wanted to keep the last "orange". Is there a way to do it with underscore.js? or lodash.js? – Vali D Oct 31 '16 at 11:14
3

The trick is to go through the array from end to beginning, so you don't mess up the indices while removing elements.

var deleteMe = function( arr, me ){
   var i = arr.length;
   while( i-- ) if(arr[i] === me ) arr.splice(i,1);
}

var arr = ["orange","red","black", "orange", "white" , "orange" ];

deleteMe( arr , "orange");

arr is now ["red", "black", "white"]

1

Or simply check all items, create a new array with non equal and return it.

var arr = ['orange', 'red', 'black', 'white'];

console.info('before: ' + JSON.stringify(arr));

var deleteElem = function ( val ) {
    var new_arr = [];
    for ( var i = 0; i < this.length; i++ ) {
        if ( this[i] !== val ) {
            new_arr.push(this[i]);
        }
    }
    return new_arr;
};

arr = deleteElem('red');

console.info('after: ' + JSON.stringify(arr));

http://jsfiddle.net/jthavn3m/

1

My approach, let's see what others have to say. It supports an "equals" method as well.

 // Remove array value
 // @param {Object} val
 Array.prototype.removeByValue = function (val) {
    for (var i = 0; i < this.length; i++) {
       var c = this[i];
       if (c == val || (val.equals && val.equals(c))) {
          this.splice(i, 1);
          break;
       }
    }
 };

Read https://stackoverflow.com/a/3010848/356726 for the impact on iterations when using prototype with Array.

Community
  • 1
  • 1
Horst Walter
  • 13,663
  • 32
  • 126
  • 228
  • Bad idea, see this post: http://stackoverflow.com/questions/948358/array-prototype-problem – MMeah Jul 09 '12 at 22:11
  • No, but I got your point: Read http://stackoverflow.com/a/3010848/356726 and use the recommend iteration over the array. Will add a comment above. The topic is not specific to the function above, but true for all Array / prototype scenarios. – Horst Walter Jul 09 '12 at 22:17
1
Array.prototype.deleteElem = function(val) {
    var index = this.indexOf(val); 
    if (index >= 0) this.splice(index, 1);
    return this;
}; 
var arr = ["orange","red","black","white"];
var arr2 = arr.deleteElem("red");
Jiri Kriz
  • 9,192
  • 3
  • 29
  • 36
0

The best way is to use splice and rebuild new array, because after splice, the length of array does't change.

Check out my answer:

function remove_array_value(array, value) {
    var index = array.indexOf(value);
    if (index >= 0) {
        array.splice(index, 1);
        reindex_array(array);
    }
}
function reindex_array(array) {
   var result = [];
    for (var key in array) {
        result.push(array[key]);
    }
    return result;
}

example:

var example_arr = ['apple', 'banana', 'lemon'];   // length = 3
remove_array_value(example_arr, 'banana');

banana is deleted and array length = 2

Terry Lin
  • 2,529
  • 22
  • 21
0

If order the array (changing positions) won't be a problem you can solve like:

var arr = ["orange","red","black","white"];
arr.remove = function ( item ) {
  delete arr[item];
  arr.sort();
  arr.pop();
  console.log(arr);
}

arr.remove('red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
-2

Here you go:

arr.deleteElem = function ( val ) {
    for ( var i = 0; i < this.length; i++ ) {
        if ( this[i] === val ) {
            this.splice( i, 1 );
            return i;
        }
    }
};

Live demo: http://jsfiddle.net/4vaE2/3/

The deleteElem method returns the index of the removed element.

var idx = arr.deleteElem( 'red' ); // idx is 1
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385