59

对此有很多问题,尤其是: jQuery 版本的 array contains使用 splice 方法的解决方案等等。然而,它们似乎都很复杂和烦人。

结合 javascript、jQuery 和 coffeescript 的强大功能,从 javascript 数组中删除元素的最干净的方法是什么?我们事先并不知道指数。在代码中:

a = [4,8,2,3]
a.remove(8)     # a is now [4,2,3]

如果没有一个好的内置方法,那么扩展 javascript 数组以支持这种方法的干净方法是什么?如果有帮助,我真的在使用数组作为集合。理想情况下,解决方案将在具有 jQuery 支持的咖啡脚本中很好地工作。此外,我不在乎速度,而是优先考虑清晰、简单的代码。

4

8 回答 8

88

咖啡脚本:

Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1

它只是拼接出 position 处的元素t,即找到的索引e(如果它实际上是找到的t > -1)。Coffeescript 将其翻译为:

Array.prototype.remove = function(e) {
    var t, _ref;
    if ((t = this.indexOf(e)) > -1) {
        return ([].splice.apply(this, [t, t - t + 1].concat(_ref = [])), _ref);
    }
};

如果你想删除所有匹配的元素,并返回一个新数组,使用 CoffeeScript 和 jQuery:

Array::remove = (v) -> $.grep @,(e)->e!=v

这转化为:

Array.prototype.remove = function(v) {
    return $.grep(this, function(e) {
        return e !== v;
    });
};

或者在没有 jQuery 的 grep 的情况下做同样的事情:

Array::filterOutValue = (v) -> x for x in @ when x!=v

翻译为:

Array.prototype.filterOutValue = function(v) {
    var x, _i, _len, _results;
    _results = [];
    for (_i = 0, _len = this.length; _i < _len; _i++) {
        x = this[_i];
        if (x !== v) {
            _results.push(x);
        }
    }
    return _results;
};
于 2011-01-28T08:18:37.177 回答
28

使用香草 Javascript:

Array.prototype.remove = function(elem) {
    var match = -1;

    while( (match = this.indexOf(elem)) > -1 ) {
        this.splice(match, 1);
    }
};

var a = [4, 8, 2, 3];

a.remove(8);

只有 jQuery:

jQuery.removeFromArray = function(value, arr) {
    return jQuery.grep(arr, function(elem, index) {
        return elem !== value;
    });
};

var a = [4, 8, 2, 3];

a = jQuery.removeFromArray(8, a);
于 2011-01-28T07:28:26.473 回答
14

使用 jQuery 非常容易:

var index = $.inArray("value", myArray);
if(index != -1)
{
  myArray.splice(index, 1);
}

笔记:

splice返回被移除的元素,所以不要这样做myArray = myArray.splice()myArray.splice(index,1)表示“从数组中删除索引'index'处的数组元素”。

$.inArray返回您要查找的值在数组中的索引,如果该值不在数组中,则返回 -1。

于 2012-05-24T18:24:04.990 回答
9

这看起来很干净且可以理解;与其他答案不同,它考虑了一个元素出现多次的可能性。

Array.prototype.remove = function (value) {
    for (var i = 0; i < this.length; ) {
        if (this[i] === value) {
            this.splice(i, 1);
        } else {
           ++i;
        }
    }
}

在 CoffeeScript 中:

Array::remove = (value) ->
    i = 0
    while i < @length
        if @[i] == value
            @splice i, 1
        else
            ++i
    return @
于 2011-01-28T07:37:29.317 回答
4

如果您还使用 CoffeeScript 创建者的underscore.js库,这里有一个可以很好地工作的单行代码:

a = _(a).reject (v)-> v is e

或者在js中:

a = _(a).reject(function(v) { return v == e; });
于 2012-02-08T22:50:41.457 回答
4

尽管您要求使用 Coffeescript 或 jQuery 的干净方法,但我发现最干净的方法是使用 vanilla javascript 方法过滤器

array.filter(function (item) { return item !== match });

它在 coffeescript 中看起来更干净,但这转化为完全相同的 javascript,所以我只认为它是视觉上的差异,而不是 coffeescript 的高级功能:

array.filter (item) -> item isnt match

旧版浏览器不支持过滤器,但 Mozilla 提供了一个符合 ECMA 标准的 polyfill 我认为这是一种非常安全的方法,因为您只是将旧浏览器引入现代标准,而您并没有在 polyfill 中发明任何新功能。

抱歉,如果您专门寻找仅 jQuery 或 Coffeescript 的方法,但我认为您主要是在要求库方法,因为您不知道纯 JavaScript 方法。

有了它,不需要库!

于 2013-04-24T20:37:06.663 回答
3

这只是对Amir 令人敬畏的解决方案的微小改动:

Array::remove = (e) -> @splice(t,1)[0] if (t = @indexOf(e)) > -1

如果列表中有元素,则返回元素,因此您可以执行以下操作:

do_something 100 if a.remove(100)

删除咖啡脚本翻译成这个 javascript:

Array.prototype.remove = function(e) {
  var t, _ref;
  if ((t = this.indexOf(e)) > -1) {
    return ([].splice.apply(this, [t, t - t + 1].concat(_ref = [])), _ref);
  }};
于 2011-11-12T13:15:41.863 回答
1

你可以试试 jQuery 的 grep 实用程序:

a = [4,8,2,3]
$.grep(a,function(v){return v!=8;})

这里可能存在性能问题,因为您在技术上导致变量引用数组;您并没有真正修改原始版本。假设原始文件没有在其他地方引用,垃圾收集器应该很快或者这个。这对我来说从来都不是问题,但其他人可能更清楚。干杯!

于 2012-07-05T23:30:53.343 回答