Prosto Trader
Prosto Trader

Reputation: 3527

Is element in array js

Following an old question, I still have a problem:

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

a.indexOf("apple") = 0

What is the easiest way to find BOTH indexes of "apple" element in array? I want to delete them both at once - is it possible?

Upvotes: 11

Views: 1471

Answers (10)

PatAtCP
PatAtCP

Reputation: 587

The fastest, most compatible, route would be to walk the array backwards in a for loop.

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

Upvotes: 1

Xotic750
Xotic750

Reputation: 23472

A couple of recursive solutions.

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

Output

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

On jsFiddle

Upvotes: 1

user1636522
user1636522

Reputation:

A good old while loop :

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

Inside a function :

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

Usage :

removeAll('apple', a);

Upvotes: 1

zzzzBov
zzzzBov

Reputation: 179046

If you need to remove elements from an array instance without generating a new array, Array.prototype.splice is a good choice:

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

If you can use a new array instance, then Array.prototype.filter is a better choice:

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

Upvotes: 2

Dmitriy Khaykin
Dmitriy Khaykin

Reputation: 5258

A for loop will do the trick. Or use forEach as T.J. Crowder suggests in his elegant answer.

I combined both an example of how to get appleIndexes and also how to "delete" them from the original array by virtue of creating a new array with all but apples in it. This is using 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]);
    }
}

Upvotes: 2

user2243479
user2243479

Reputation:

if you want to remove all occurrences, you could also use Array.splice recursively

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

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

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074268

What is the easiest way to find BOTH indexes of "apple" element in array?

You asked that, but also asked about deleting. I'll tackle indexes first, then deletion.

Indexes:

There's no shortcut, you have to loop through it. You can use a simple for loop:

var indexes = [];
var index;

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

Or two ES5 options: forEach:

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

Or reduce:

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

...although frankly that does't really buy you anything over forEach.

Deletion:

From the end of your question:

I want to delete them both at once - is it possible?

Sort of. In ES5, there's a filter function you can use, but it creates a new array.

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

That basically does this (in general terms):

var newa = [];
var index;

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

Upvotes: 9

c-smile
c-smile

Reputation: 27460

That's the task for filter method:

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

Upvotes: 15

Hidde
Hidde

Reputation: 11931

Use the start parameter in array.indexOf(element, start), as described in http://www.w3schools.com/jsref/jsref_indexof_array.asp.

Example:

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

Upvotes: 1

Samir Talwar
Samir Talwar

Reputation: 14330

Array.indexOf takes a second, optional argument: the index to start from. You can use this inside a loop to specify to start from the last one.

var indices = [],
    index = 0;

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

Once indexOf returns -1, which signals "no element found", the loop will break. The indices array will then hold the correct indices.

There is an example on the Mozilla page on indexOf which has some equivalent code. I'm not so much of a fan because of the increased duplication, but it is shorter, which is nice.

Upvotes: 3

Related Questions