Чистый способ удалить элемент из массива javascript (с помощью jQuery, coffeescript)

Есть много вопросов об этом, не в последнюю очередь: jQuery версия массива содержит, решение с использованием метода сращивания и многое другое. Однако все они кажутся сложными и раздражающими.

С объединенными полномочиями javascript, jQuery и coffeescript, какой самый чистый способ удалить элемент из массива javascript? Мы не знаем индекс заранее. В коде:

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

Неудачный хороший встроенный метод, что является чистым способом расширения массивов javascript для поддержки такого метода? Если это помогает, я действительно использую массивы в качестве наборов. Решения будут идеально работать в coffeescript с поддержкой jQuery. Кроме того, мне было все равно, о скорости, но вместо этого расставьте приоритет четкого простого кода.

Ответы

Ответ 1

CoffeeScript:

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

Что просто связывает элемент в позиции 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;
};

Ответ 2

Использование ванили 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);

Ответ 3

Это очень просто с jQuery:

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

Примечания:

splice возвращает элементы, которые были удалены, поэтому не делайте myArray = myArray.splice(). myArray.splice(index,1) означает "удалить элемент массива из индекса 'index' из массива".

$.inArray возвращает индекс в массив значения, которое вы ищете, или -1, если значение не находится в массиве.

Ответ 4

Это кажется довольно чистым и понятным; в отличие от других ответов, он учитывает возможность появления элемента более одного раза.

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 @

Ответ 5

если вы также используете библиотеку CoffeeScript underscore.js, здесь один лайнер, который будет работать красиво:

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

или в js:

a = _(a).reject(function(v) { return v == e; });

Ответ 6

Несмотря на то, что вы просите о чистом подходе с использованием Coffeescript или jQuery, я считаю, что самый чистый подход использует метод javascript vanilla filter:

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

Он выглядит более чистым в coffeescript, но это переводит на тот же самый javascript, поэтому я рассматриваю его только как визуальную разницу, а не расширенную функцию coffeescript:

array.filter (item) -> item isnt match

Фильтр не поддерживается в устаревших браузерах, но Mozilla предоставляет polyfill, который соответствует стандарту ECMA. Я думаю, что это абсолютно безопасный подход, потому что вы только приносите старые браузеры к современным стандартам, и вы не изобретаете никаких новых функций в polyfill.

Извините, если вы специально искали только метод jQuery или Coffeescript, но я думаю, что вы в основном просили библиотечный метод, потому что вы не знали о чистом методе только javascript.

Там у вас есть, не нужны библиотеки!

Ответ 7

Это небольшое изменение в Амире удивительное решение:

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

который возвращает элемент iff в списке, поэтому вы можете сделать что-то вроде:

do_something 100 if a.remove(100)

Удаление кофе script переводится на этот 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);
  }};

Ответ 8

Вы можете просто попробовать утилиту jQuery grep:

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

Здесь может быть проблема с производительностью, так как вы технически вызываете переменную для ссылки на новый массив; вы на самом деле не изменяете оригинал. Предполагая, что оригинал не упоминается где-то еще, сборщик мусора должен принять или это довольно быстро. Это никогда не было проблемой для меня, но другие могли бы знать лучше. Ура!