57

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

4

10 Answers 10

106

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.

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

7 Comments

Also, you would have to augment your array to support .indexOf() which isn't supported in some older versions of IE.
very dangerous, because if "red" is not in an array it deletes "white"
@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.
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.
Answer has been fixed, upvoted, with the mentioned caveat about .indexOf() compatibility.
|
56

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

1 Comment

4

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

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

arr = _.without(arr, "red");

1 Comment

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?
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"]

Comments

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

Comments

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.

2 Comments

No, but I got your point: Read 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.
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/

Comments

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

Comments

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>

Comments

-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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.