How do I remove a particular element from an array

2018-12-30 22:45发布

I have an array of integers, and I'm using the .push() method to add elements to it.

Is there a simple way to remove a specific element from an array? The equivalent of something like array.remove(int);.

I have to use core JavaScript - no frameworks are allowed.

30条回答
看淡一切
2楼-- · 2018-12-30 23:23

Too old to reply, but may it help someone, by providing a predicate instead of a value.

NOTE: it will update the given array, and return affected rows

Usage

var removed = helper.removeOne(arr, row => row.id === 5 );

var removed = helper.remove(arr, row => row.name.startsWith('BMW'));

Definition

var helper = {

    // Remove and return the first occurrence     

    removeOne: function(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                return array.splice(i, 1);
            }
        }
    },

    // Remove and return all occurrences  

    remove: function(array, predicate) {
        var removed = [];

        for (var i = 0; i < array.length;) {

            if (predicate(array[i])) {
                removed.push(array.splice(i, 1));
                continue;
            }

            i++;                
        }

        return removed;
    }
};
查看更多
不再属于我。
3楼-- · 2018-12-30 23:23

Based on all the answers which were mainly correct and taking into account the best practices suggested (especially not using Array.prototype directly), I came up with the below code:

function arrayWithout(arr, values) {
  var isArray = function(canBeArray) {
    if (Array.isArray) {
      return Array.isArray(canBeArray);
    }
    return Object.prototype.toString.call(canBeArray) === '[object Array]';
  };

  var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
  var arrCopy = arr.slice(0);

  for (var i = arrCopy.length - 1; i >= 0; i--) {
    if (excludedValues.indexOf(arrCopy[i]) > -1) {
      arrCopy.splice(i, 1);
    }
  }

  return arrCopy;
}

Reviewing the above function, despite the fact that it works fine, I realised there could be some performance improvement. Also using ES6 instead of ES5 is a much better approach. To that end, this is the improved code:

const arrayWithoutFastest = (() => {
  const isArray = canBeArray => ('isArray' in Array) 
    ? Array.isArray(canBeArray) 
    : Object.prototype.toString.call(canBeArray) === '[object Array]';

  let mapIncludes = (map, key) => map.has(key);
  let objectIncludes = (obj, key) => key in obj;
  let includes;

  function arrayWithoutFastest(arr, ...thisArgs) {
    let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;

    if (typeof Map !== 'undefined') {
      withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
      includes = mapIncludes;
    } else {
      withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {}); 
      includes = objectIncludes;
    }

    const arrCopy = [];
    const length = arr.length;

    for (let i = 0; i < length; i++) {
      // If value is not in exclude list
      if (!includes(withoutValues, arr[i])) {
        arrCopy.push(arr[i]);
      }
    }

    return arrCopy;
  }

  return arrayWithoutFastest;  
})();

How to use:

const arr = [1,2,3,4,5,"name", false];

arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)

I am currently writing a blog post in which I have benchmarked several solutions for Array without problem and compared the time it takes to run. I will update this answer with the link once I finish that post. Just to let you know, I have compared the above against lodash's without and in case the browser supports Map, it beats lodash! Notice that I am not using Array.prototype.indexOf or Array.prototype.includes as wrapping the exlcudeValues in a Map or Object makes querying faster!

查看更多
萌妹纸的霸气范
4楼-- · 2018-12-30 23:24

If you have complex objects in the array you can use filters? In situations where $.inArray or array.splice is not as easy to use. Especially if the objects are perhaps shallow in the array.

E.g. if you have an object with an Id field and you want the object removed from an array:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});
查看更多
低头抚发
5楼-- · 2018-12-30 23:25

You have 1 to 9 array and you want remove 5 use below code.

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);


If you want to multiple value ex :- 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 5 removed", newNumberArray);


If you want to remove array value in array ex :- [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

includes supported browser is link

查看更多
浮光初槿花落
6楼-- · 2018-12-30 23:26

Edited on 2016 october

In this code example I use "array.filter(...)" function to remove unwanted items from array, this function doesn't change the original array and creates a new one. If your browser don't support this function (e.g. IE before version 9, or Firefox before version 1.5), consider using the filter polyfill from Mozilla.

Removing item (ECMA-262 Edition 5 code aka oldstyle JS)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) { 
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

Removing item (ES2015 code)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

IMPORTANT ES2015 "() => {}" arrow function syntax is not supported in IE at all, Chrome before 45 version, Firefox before 22 version, Safari before 10 version. To use ES2015 syntax in old browsers you can use BabelJS


Removing multiple items (ES2016 code)

An additional advantage of this method is that you can remove multiple items

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

IMPORTANT "array.includes(...)" function is not supported in IE at all, Chrome before 47 version, Firefox before 43 version, Safari before 9 version and Edge before 14 version so here is polyfill from Mozilla

Removing multiple items (Cutting-edge experimental JavaScript ES2018?)

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

Try it yourself in BabelJS :)

Reference

查看更多
萌妹纸的霸气范
7楼-- · 2018-12-30 23:26

OK, for example you are having the array below:

var num = [1, 2, 3, 4, 5];

And we want to delete number 4, you can simply do the below code:

num.splice(num.indexOf(4), 1); //num will be [1, 2, 3, 5];

If you reusing this function, you write a reusable function which will be attached to Native array function like below:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1) return;
  this.splice(i, 1); //num.remove(5) === [1, 2, 3];
}

But how about if you are having the below array instead with few [5]s in the Array?

var num = [5, 6, 5, 4, 5, 1, 5];

We need a loop to check them all, but easier and more efficient way is using built-in JavaScript functions, so we write a function which use filter like below instead:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) //return [1, 2, 3, 4, 6]

Also there are third parties libraries which do help you to do this, like Lodash or Underscore, for more info look at lodash _.pull, _.pullAt or _.without.

查看更多
登录 后发表回答