Reputation: 3527
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
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
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
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
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
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
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
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.
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
.
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
Reputation: 27460
That's the task for filter method:
var noApples = a.filter(function(el) { return el != "apple"; })
Upvotes: 15
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
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