如何从JavaScript中删除数组中的特定元素?

[英]How do I remove a particular element from an array in JavaScript?


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

我有一个整数数组,我使用.push()方法为它添加元素。

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

是否有从数组中移除特定元素的简单方法?类似于array.remove(int);

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

我必须使用核心JavaScript——不允许使用框架。

60 个解决方案

#1


8294  

Find the index of the array element you want to remove, then remove that index with splice.

查找要删除的数组元素的索引,然后用splice删除该索引。

var array = [2, 5, 9];
var index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}
// array = [2, 9]

The second parameter of splice is the number of elements to remove. Note that splice modifies the array in place and returns a new array containing the elements that have been removed.

splice的第二个参数是要删除的元素的数量。注意,splice修改了数组,并返回一个包含已删除元素的新数组。


Note: browser support for indexOf is limited; it is not supported in Internet Explorer 7 and 8.

注意:浏览器对indexOf的支持是有限的;它在Internet Explorer 7和8中不受支持。

If you need indexOf in an unsupported browser, try the following polyfill. Find more info about this polyfill here.

如果您需要在不支持的浏览器中进行索引,请尝试下面的polyfill。在这里找到更多关于这个polyfill的信息。

Array.prototype.indexOf || (Array.prototype.indexOf = function(d, e) {
    var a;
    if (null == this) throw new TypeError('"this" is null or not defined');
    var c = Object(this),
        b = c.length >>> 0;
    if (0 === b) return -1;
    a = +e || 0;
    Infinity === Math.abs(a) && (a = 0);
    if (a >= b) return -1;
    for (a = Math.max(0 <= a ? a : b - Math.abs(a), 0); a < b;) {
        if (a in c && c[a] === d) return a;
        a++
    }
    return -1
});

#2


813  

I don't know how you are expecting array.remove(int) to behave. There are three possibilities I can think of that you might be wanting.

我不知道你是怎么期望array.remove(int)的。我可以想到三种可能性,你可能想要。

To remove an element of an array at an index i:

在索引i中删除数组元素:

array.splice(i, 1);

If you want to remove every element with value number from the array:

如果您想要从数组中移除所有具有值的元素:

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

If you just want to make the element at index i no longer exist, but you don't want the indexes of the other elements to change:

如果你只是想让索引中的元素不再存在,但你不希望其他元素的索引改变:

delete array[i];

#3


550  

Edited on 2016 october

  • Do it simple, intuitive and explicit (https://en.wikipedia.org/wiki/Occam%27s_razor)
  • 做到简单、直观和明确(https://en.wikipedia.org/wiki/Occam%27s_razor)
  • Do it immutable (original array stay unchanged)
  • 不可变(原始数组不变)
  • Do it with standard JS functions, if your browser don't support them - use polyfill
  • 如果你的浏览器不支持,使用标准的JS函数,使用polyfill ?

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.

在这个代码示例中,我使用“array.filter(…)”函数从数组中删除不需要的项,这个函数不会改变原始数组,并创建一个新的数组。如果您的浏览器不支持这个功能(例如在version 9之前,或者在版本1.5之前的Firefox),请考虑使用Mozilla的过滤器polyfill。

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

重要的ES2015“()=>{}”箭头函数语法在IE中不受支持,在45版本之前,Firefox在22版本之前,Safari在10版本之前。要在旧浏览器中使用ES2015语法,您可以使用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

重要的“array.include(…)”功能在IE中根本不受支持,在47版之前,Firefox在43版之前,Safari在9版之前,在14版之前,这里是Mozilla的polyfill。

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

在BabelJS中自己尝试一下:)

Reference

参考

#4


329  

Depends on whether you want to keep an empty spot or not.

这取决于你是否想保留一个空位。

If you do want an empty slot, delete is fine:

如果你想要一个空槽,删除是好的:

delete array[ index ];

If you don't, you should use the splice method:

如果没有,则应该使用splice方法:

array.splice( index, 1 );

And if you need the value of that item, you can just store the returned array's element:

如果您需要该项目的值,您可以只存储返回的数组元素:

var value = array.splice( index, 1 )[0];

In case you want to do it in some order, you can use array.pop() for the last one or array.shift() for the first one (and both return the value of the item too).

如果您想按某种顺序执行,您可以使用array.pop()来进行最后一个或array.shift()来进行第一个操作(同时还可以返回该项目的值)。

And if you don't know the index of the item, you can use array.indexOf( item ) to get it (in a if() to get one item or in a while() to get all of them). array.indexOf( item ) returns either the index or -1 if not found. 

如果你不知道这个项目的索引,你可以使用数组。indexOf(项目)获得它(在一个if()中获得一个项目或在一段时间内得到全部)。数组中。索引(项)返回索引或-1,如果没有找到。

#5


204  

A friend was having issues in Internet Explorer 8, and showed me what he did. I told him it was wrong, and he told me he got the answer here. The current top answer will not work in all browsers (Internet Explorer 8 for example), and it will only remove the first occurrence of the item.

一个朋友在Internet Explorer 8上遇到了问题,并向我展示了他所做的事情。我告诉他这是错误的,他告诉我他得到了答案。当前的top答案不会在所有浏览器中工作(例如Internet Explorer 8),它只会删除该项目的第一次出现。

Remove ALL instances from an array

  function remove(arr, item) {
      for(var i = arr.length; i--;) {
          if(arr[i] === item) {
              arr.splice(i, 1);
          }
      }
  }

It loops through the array backwards (since indices and length will change as items are removed) and removes the item if it's found. It works in all browsers.

它循环遍历数组(因为索引和长度会随着项的移除而改变),如果发现了该项,则删除该项。它适用于所有的浏览器。

#6


117  

There are two major approaches:

主要有两种方法:

  1. splice(): anArray.splice(index, 1);

    接头():anArray。拼接(指数(1);

  2. delete: delete anArray[index];

    删除:删除anArray(指数);

Be careful when you use delete for an array. It is good for deleting attributes of objects but not so good for arrays. It is better to use splice for arrays.

当您使用delete作为数组时,要小心。它有助于删除对象的属性,但对数组不太好。对于数组,最好使用splice。

Keep in mind that when you use delete for an array you could get wrong results for anArray.length. In other words, delete would remove the element but wouldn't update the value of length property.

请记住,当您使用delete作为数组时,您可能会在anArray.length中得到错误的结果。换句话说,delete将删除元素,但不会更新length属性的值。

You can also expect to have holes in index numbers after using delete, e.g. you could end up with having indexes 1,3,4,8,9,11 and length as it was before using delete. In that case, all indexed for loops would crash, since indexes are no longer sequential.

在使用delete之后,您还可以期望在索引号上有漏洞,例如,您可能会在使用delete之前拥有索引1、3、4、8、9、11和长度。在这种情况下,所有的循环索引都将崩溃,因为索引不再是连续的。

If you are forced to use delete for some reason, then you should use for each loops when you need to loop through arrays. As the matter of fact, always avoid using indexed for loops, if possible. That way the code would be more robust and less prone to problems with indexes.

如果由于某种原因被迫使用delete,那么当需要对数组进行循环时,应该使用每个循环。事实上,如果可能的话,总是避免使用索引进行循环。这样,代码就会更加健壮,并且不太容易出现索引问题。

#7


90  

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);

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

var rooms = ['hello', 'something']

rooms = rooms.remByVal('hello')

console.log(rooms)

#8


73  

There is no need to use indexOf or splice. However, it performs better if you only want to remove one occurrence of an element.

不需要使用indexOf或splice。但是,如果只希望删除元素的一个出现,它的性能会更好。

Find and move (move):

找到并移动(移动):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

Use indexOf and splice (indexof):

使用indexOf和splice (indexOf):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

Use only splice (splice):

只使用拼接(拼接):

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

Run-times on nodejs for array with 1000 elements (average over 10000 runs):

对于具有1000个元素的数组的nodejs的运行时间(平均超过10000个运行):

indexof is approximately 10x slower than move. Even if improved by removing the call to indexOf in splice it performs much worse than move.

indexof大约比移动慢10倍。即使将调用删除到splice中,它的性能也比移动更糟糕。

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms

#9


48  

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

#10


43  

John Resig posted a good implementation:

John Resig发布了一个很好的实现:

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

If you don’t want to extend a global object, you can do something like the following, instead:

如果您不想扩展一个全局对象,您可以执行如下操作:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

But the main reason I am posting this is to warn users against the alternative implementation suggested in the comments on that page (Dec 14, 2007):

但我发布这篇文章的主要原因是为了提醒用户反对在该页面的评论中提出的替代方案(2007年12月14日):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

It seems to work well at first, but through a painful process I discovered it fails when trying to remove the second to last element in an array. For example, if you have a 10-element array and you try to remove the 9th element with this:

起初,它似乎运行良好,但是通过一个痛苦的过程,我发现它在试图删除数组中的第二个元素时失败了。例如,如果你有一个10元数组,你试着去掉第9个元素:

myArray.remove(8);

You end up with an 8-element array. Don't know why but I confirmed John's original implementation doesn't have this problem.

最后得到一个8元数组。不知道为什么,但是我确认了John的原始实现没有这个问题。

#11


43  

Underscore.js can be used to solve issues with multiple browsers. It uses in-build browser methods if present. If they are absent like in the case of older Internet Explorer versions it uses its own custom methods.

下划线。js可以用来解决多个浏览器的问题。如果存在,它使用内置的浏览器方法。如果它们不像以前的Internet Explorer版本那样,它使用自己的自定义方法。

A simple example to remove elements from array (from the website):

一个简单的例子从数组中删除元素(从网站):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]

#12


41  

You can do it easily with filter method:

你可以用filter方法很容易地做到:

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log( remove([1, 2, 1, 0, 3, 1, 4], 1) );

This removes all elements from the array and also works faster then combination of slice and indexOf

这样就可以从数组中删除所有元素,并且可以更快地实现slice和indexOf的组合。

#13


32  

You can use ES6.

您可以使用ES6。

var array=['1','2','3','4','5','6']
var index = array.filter((value)=>value!='3');

Output :

输出:

["1", "2", "4", "5", "6"]

#14


30  

If you want a new array with the deleted positions removed, you can always delete the specific element and filter out the array. It might need an extension of the array object for browsers that don't implement the filter method but in the long term its easier since all you do is this:

如果您想要删除删除位置的新数组,您可以始终删除特定的元素并过滤出数组。它可能需要对不实现过滤方法的浏览器的数组对象进行扩展,但从长远来看,这更容易,因为你所做的就是:

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

Should display [1, 2, 3, 4, 6]

应显示[1,2,3,4,6]

#15


27  

Check out this code. It works in every major browser.

看看这段代码。它适用于每一个主要的浏览器。

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

Call this function

调用这个函数

remove_item(array,value);

#16


25  

You can use lodash _.pull (mutate array), _.pullAt (mutate array) or _.without (does't mutate array),

您可以使用lodash _。拉(变异数组),_。pullAt (mutate数组)或_。没有(不改变数组),

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']

#17


21  

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:

我们想删除4,你可以简单地做下面的代码:

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?

但是,如果数组中只有很少的[5],那么下面的数组是怎样的呢?

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:

我们需要一个循环来检查它们,但是更简单和更有效的方法是使用内置的JavaScript函数,所以我们编写一个函数,它使用如下的过滤器:

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.

还有第三方库可以帮助您完成这类工作,比如Lodash或下划线,以获得更多的信息。拉,_。pullAt或_.without。

#18


20  

I'm pretty new to JavaScript and needed this functionality. I merely wrote this:

我对JavaScript很熟悉,需要这个功能。我仅仅是写这个:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

Then when I want to use it:

当我想用它的时候:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

Output - As expected. ["item1", "item1"]

输出——如预期。[" item1”、“item1”)

You may have different needs than I, so you can easily modify it to suit them. I hope this helps someone.

您可能有不同的需求,所以您可以很容易地修改它以适合他们。我希望这能帮助别人。

#19


18  

ES6 & without mutation: (October 2016)

const removeByIndex = (list, index) =>
  [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];

Then :

然后:

removeByIndex([33,22,11,44],1) //=> [33,11,44]

#20


17  

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.

如果数组中有复杂对象,可以使用过滤器?在美元的情况下。inArray或数组。splice并不那么容易使用。特别是当对象在数组中很浅的时候。

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

如果你有一个带Id字段的对象,你想要从数组中移除对象:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

#21


15  

A more modern, ECMAScript 2015 (formerly known as Harmony or ES 6) approach. Given:

一个更现代的,ECMAScript 2015(以前称为Harmony或ES 6)的方法。考虑到:

const items = [1, 2, 3, 4];
const index = 2;

Then:

然后:

items.filter((x, i) => i !== index);

Yielding:

收益率:

[1, 2, 4]

You can use Babel and a polyfill service to ensure this is well supported across browsers.

您可以使用Babel和polyfill服务来确保在不同的浏览器中得到良好的支持。

#22


15  

Update: This method is recommended only if you cannot use ECMAScript 2015 (formerly known as ES6). If you can use it, other answers here provide much neater implementations.

更新:只有在2015年不能使用ECMAScript(以前称为ES6)的情况下,才推荐使用此方法。如果您可以使用它,那么这里的其他答案提供了更多的neater实现。


This gist here will solve your problem, and also deletes all occurrences of the argument instead of just 1 (or a specified value).

这里的这个要点将解决您的问题,并删除参数的所有出现,而不是仅仅1(或指定的值)。

Array.prototype.destroy = function(obj){
    // Return null if no objects were found and removed
    var destroyed = null;

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

        // Use while-loop to find adjacent equal objects
        while(this[i] === obj){

            // Remove this[i] and store it within destroyed
            destroyed = this.splice(i, 1)[0];
        }
    }

    return destroyed;
}

Usage:

用法:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]

#23


14  

You should never mutate your array your array. As this is against functional programming pattern. What you can do is create a new array without referencing the array you want to change data of using es6 method filter;

您不应该更改数组的数组。因为这是针对函数式编程模式的。您可以做的是创建一个新的数组,而无需引用您想要更改的使用es6方法筛选器的数据的数组;

var myArray = [1,2,3,4,5,6];

Suppose you want to remove 5 from the array you can simply do it like this.

假设你想从数组中移除5,你可以这样做。

myArray = myArray.filter(value => value !== 5);

This will give you a new array without the value you wanted to remove. So the result will be

这将给您一个新的数组,没有您想要删除的值。结果是。

 [1,2,3,4,6]; // 5 has been removed from this array

For further understanding you can read the MDN documentation on Array.filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

为了进一步了解,您可以阅读关于数组的MDN文档。过滤器https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

#24


9  

I know there are a lot of answers already, but many of them seem to over complicate the problem. Here is a simple, recursive way of removing all instances of a key - calls self until index isn't found. Yes, it only works in browsers with indexOf, but it's simple and can be easily polyfilled.

我知道已经有很多的答案了,但是他们中的许多似乎把问题复杂化了。这里有一个简单的、递归的方法,可以删除键调用self的所有实例,直到找到索引为止。是的,它只在带有索引的浏览器中工作,但它很简单,而且很容易被填充。

Stand-alone function

独立的功能

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

Prototype method

原型方法

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}

#25


9  

Remove by Index

通过索引删除

Function that return a copy of array without the element at index.

函数,该函数返回数组的副本,而不返回索引中的元素。

/**
* removeByIndex
* @param {Array} array
* @param {Number} index
*/
function removeByIndex(array, index){
    return array.filter(function(elem, _index){
        return index != _index;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByIndex(l, 1));

$> [ 1, 4, 5, 6, 7 ]

Remove by Value

删除的值

Function that return a copy of array without the Value.

函数,返回一个没有值的数组的副本。

/**
* removeByValue
* @param {Array} array
* @param {Number} value
*/
function removeByValue(array, value){
    return array.filter(function(elem, _index){
        return value != elem;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByValue(l, 5));

$> [ 1, 3, 4, 6, 7]

#26


8  

You can do a backward loop to make sure not to screw up the indexes, if there are multiple instances of the element.

如果有多个元素实例,则可以执行向后循环,以确保不破坏索引。

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

Live Demo

#27


8  

I think many of the JavaScript instructions are not well thought out for functional programming. Splice returns the deleted element where most of the time you need the reduced array. This is bad.

我认为许多JavaScript指令对于函数式编程来说并不是很好。Splice返回删除的元素,在大多数情况下,您需要减少数组。这是不好的。

Imagine you are doing a recursive call and have to pass an array with one less item, probably without the current indexed item. Or imagine you are doing another recursive call and has to pass an array with an element pushed.

假设您正在执行一个递归调用,并且必须传递一个较少项的数组,可能没有当前的索引项。或者假设您正在执行另一个递归调用,并且必须传递一个带有元素的数组。

In neither of these cases you can do myRecursiveFunction(myArr.push(c)) or myRecursiveFunction(myArr.splice(i,1)). The first idiot will in fact pass the length of the array and the second idiot will pass the deleted element as a parameter.

在这两种情况下,您都不能执行myArr.push(c)或myr .splice函数(myArr.splice(i,1))。第一个白痴实际上会传递数组的长度,第二个白痴会将被删除的元素作为参数传递。

So what I do in fact... For deleting an array element and passing the resulting to a function as a parameter at the same time I do as follows

所以我实际上…为了删除数组元素并将结果作为参数传递给函数,我这样做如下所示。

myRecursiveFunction(myArr.slice(0,i).concat(a.slice(i+1)))

When it comes to push that's more silly... I do like,

说到push,这更傻……我喜欢,

myRecursiveFunction((myArr.push(c),myArr))

I believe in a proper functional language a method mutating the object it's called upon must return a reference to the very object as a result.

我相信一个适当的函数式语言是一种改变被调用对象的方法,它必须返回一个对这个对象的引用。

#28


8  

2017-05-08

2017-05-08

Most of the given answers work for strict comparison, meaning that both objects reference the exact same object in memory (or are primitive types), but often you want to remove a non-primitive object from an array that has a certain value. For instance, if you make a call to a server and want to check a retrieved object against a local object.

大多数给定的答案都适用于严格的比较,这意味着两个对象在内存中引用了相同的对象(或者是基本类型),但是通常您希望从具有一定值的数组中删除非原始对象。例如,如果您向服务器发出一个调用,并希望检查检索到的对象与本地对象。

const a = {'field': 2} // Non-primitive object
const b = {'field': 2} // Non-primitive object with same value
const c = a            // Non-primitive object that reference the same object as "a"

assert(a !== b) // Don't reference the same item, but have same value
assert(a === c) // Do reference the same item, and have same value (naturally)

//Note: there are many alternative implementations for valuesAreEqual
function valuesAreEqual (x, y) {
   return  JSON.stringify(x) === JSON.stringify(y)
}


//filter will delete false values
//Thus, we want to return "false" if the item
// we want to delete is equal to the item in the array
function removeFromArray(arr, toDelete){
    return arr.filter(target => {return !valuesAreEqual(toDelete, target)})
}

const exampleArray = [a, b, b, c, a, {'field': 2}, {'field': 90}];
const resultArray = removeFromArray(exampleArray, a);

//resultArray = [{'field':90}]

There are alternative/faster implementations for valuesAreEqual, but this does the job. You can also use a custom comparator if you have a specific field to check (for example, some retrieved UUID vs a local UUID).

对于valuesAreEqual,有其他的/更快的实现,但是这是工作。您还可以使用自定义比较器,如果您有一个特定的字段来检查(例如,一些检索UUID和一个本地UUID)。

Also note that this is a functional operation, meaning that it does not mutate the original array.

还要注意,这是一个函数操作,这意味着它不会改变原始数组。

#29


7  

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:

回顾上面的功能,尽管它运行良好,我意识到可能会有一些性能改进。使用ES6代替ES5是一种更好的方法。为此目的,这是改进后的代码:

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! (https://jsperf.com/array-without-benchmark-against-lodash)

我目前正在写一篇博客文章,在这篇文章中,我对数组的几个解决方案进行了基准测试,并比较了运行的时间。一旦我完成了这篇文章,我将用这个链接更新这个答案。为了让你知道,我已经比较了以上对lodash的没有,如果浏览器支持地图,它打败了lodash!注意,我没有使用Array.prototype。indexOf或Array.prototype。包括在映射或对象中包装exlcudeValues使查询更快!(https://jsperf.com/array-without-benchmark-against-lodash)

#30


6  

Create new array:

创建新数组:

var my_array = new Array();

Add elements to this array:

向该数组添加元素:

my_array.push("element1");

The function indexOf (Returns index or -1 when not found) :

函数索引(当未找到时返回索引或-1):

var indexOf = function(needle) 
{
    if(typeof Array.prototype.indexOf === 'function') // newer browsers
    {
        indexOf = Array.prototype.indexOf;
    } 
    else // older browsers
    {
        indexOf = function(needle) 
        {
            var index = -1;

            for(var i = 0; i < this.length; i++) 
            {
                if(this[i] === needle) 
                {
                    index = i;
                    break;
                }
            }
            return index;
        };
    }

    return indexOf.call(this, needle);
};

Check index of this element (tested with firefox and IE8+):

检查该元素的索引(用firefox和IE8+测试):

var index = indexOf.call(my_array, "element1");

Remove 1 element located at index from the array

从数组中移除位于索引处的1个元素。

my_array.splice(index, 1);

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2011/04/23/41ffa943a68afbfb6e4585db44c1d9a.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com