Является элементом в массиве js

Следуя старому вопросу, у меня все еще есть проблема:

a = ["apple", "banana", "orange", "apple"];

a.indexOf("apple") = 0

Каков самый простой способ найти BOTH-индексы "яблочного" элемента в массиве? Я хочу удалить их оба сразу - возможно ли это?

Ответ 1

Это задача для метода фильтрации:

var noApples = a.filter(function(el) { return el != "apple"; })

Ответ 2

Каков самый простой способ найти BOTH-индексы элемента "apple" в массиве?

Ты спросил об этом, но также спросил об удалении. Сначала я займусь индексами, а затем удалю.

Индексы:

Нет ярлыка, вам нужно пройти через него. Вы можете использовать простой цикл for:

var indexes = [];
var index;

for (index = 0; index < a.length; ++index) {
    if (a[n] === "apple") {
        indexes.push(index);
    }
});

Или два параметра ES5: forEach:

var indexes = [];
a.forEach(function(entry, index) {
    if (entry === "apple") {
        indexes.push(index);
    }
});

Или reduce:

var indexes = a.reduce(function(acc, entry, index) {
    if (entry === "apple") {
        acc.push(index);
    }
    return acc;
}, []);

... хотя, честно говоря, это действительно не купит вам что-либо более forEach.

Удаление:

С конца вашего вопроса:

Я хочу удалить их оба сразу - возможно ли это?

Сорт. В ES5 существует функция filter, которую вы можете использовать, но она создает новый массив.

var newa = a.filter(function(entry) {
    return entry !== "apple";
});

Это в основном делает это (в общих чертах):

var newa = [];
var index;

for (index = 0; index < a.length; ++index) {
    if (a[n] !== "apple") {
        newa.push(index);
    }
});

Ответ 3

Array.indexOf берет второй необязательный аргумент: индекс для начала. Вы можете использовать это внутри цикла, чтобы указать, чтобы начать с последнего.

var indices = [],
    index = 0;

while (true) {
    index = a.indexOf("apple", index);
    if (index < 0) {
        break;
    }
    indices.push(index);
}

Как только indexOf возвращает -1, который сигнализирует "элемент не найден", цикл прерывается. Массив indices будет содержать правильные индексы.

Существует пример на странице Mozilla indexOf, в котором есть эквивалентный код. Я не настолько поклонник из-за увеличения дублирования, но он короче, что приятно.

Ответ 4

A for loop выполнит трюк. Или используйте forEach как T.J. Кроудер предлагает в своем изящном ответе.

Я объединил и пример того, как получить appleIndexes, а также как "удалить" их из исходного массива за счет создания нового массива со всеми, кроме яблок. Это использует oldSchool JavaScript:)

a = ["apple", "banana", "orange", "apple"];

appleIndexes = [];
arrayOfNotApples = [];

for (var i = 0; i < a.length; i++)
{
    if (a[i] == "apple")
    {
        appleIndexes.push(i);
    } else {
        arrayOfNotApples.push(a[i]);
    }
}

Ответ 5

Если вам нужно удалить элементы из экземпляра массива без генерации нового массива, Array.prototype.splice является хорошим выбором:

var a,
    i;
a = ["apple", "banana", "orange", "apple"];
for (i = a.indexOf('apple'); i > -1; i = a.indexOf('apple')) {
    a.splice(i, 1);
}

Если вы можете использовать новый экземпляр массива, то Array.prototype.filter - лучший выбор:

var a,
    b;
a = ["apple", "banana", "orange", "apple"];
b = a.filter(function (item, index, array) {
    return item !== 'apple';
});

Ответ 6

Используйте параметр start в array.indexOf(element, start), как описано в http://www.w3schools.com/jsref/jsref_indexof_array.asp.

Пример:

var a = [1, 3, 4, 1];
var searchElement = 1;
var foundIndices = [];
var startIndex = 0;

while ((index = a.indexOf(searchElement, startIndex)) != -1) {
       foundIndices.push(index);
       startIndex = index + 1;
}
console.log(foundIndices); // Outputs [0, 3];

Ответ 7

если вы хотите удалить все вхождения, вы также можете использовать Array.splice рекурсивно

function remove(list, item) {
    if(list.indexOf(item)<0)
        return list;

    list.splice(list.indexOf(item),1);
    return list;
}

Ответ 8

Старый старик while:

var i = a.length;
while (i--) {
    if (a[i] === 'apple') {
        a.splice(i, 1); 
    }
}

Внутри функции:

function removeAll(value, array) {
    var i = array.length;
    while (i--) {
        if (array[i] === value) {
            array.splice(i, 1); 
        }
    }
    return array;
}

Использование:

removeAll('apple', a);

Ответ 9

Несколько рекурсивных решений.

Javascript

function indexesOf(array, searchElement, fromIndex) {
    var result = [],
        index = array.indexOf(searchElement, fromIndex >>> 0);

    if (index === -1) {
        return result;
    }

    return result.concat(index, indexesOf(array, searchElement, index + 1));
}

function removeFrom(array, searchElement, fromIndex) {
    var index = array.indexOf(searchElement, fromIndex >>> 0);

    if (index !== -1) {
        array.splice(index, 1);
        removeFrom(array, searchElement, index);
    }

    return array;
}

var a = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0];

console.log(indexesOf(a, 0));
console.log(removeFrom(a, 0));

Выход

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Вкл jsFiddle

Ответ 10

Самый быстрый, самый совместимый маршрут - это перемещение массива назад в цикле for.

for (var a = array.length;a--;)
     if (array[a] == 'apple') array.splice(a,1);