Reputation: 1757
I have the following list
<ul id="serial_list" class="list-group scroll">
<li class="list-group-item template">template</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
<li class="list-group-item">eee</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
</ul>
And I want to delete each item based on each element of an array.
Approach1:
numbers = ["SNID", "abc", "eee", "SNID", "abc"];
// find each li
var list = $(serial_list).find('li:not(.template)');
numbers.forEach(function(number) {
$(list).each(function(index, item) {
// console.log(number);
if (number == $(item).html()) {
$(item).remove();
return false;
}
});
});
The expected result will be
<ul id="serial_list" class="list-group scroll">
<li class="list-group-item template">template</li>
</ul>
However, the actual result is
<ul id="serial_list" class="list-group scroll">
<li class="list-group-item template">template</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
</ul>
The number of times calling remove() is the same as the length of the array.
However, if I update the list when loop each number (Approach2) , the result is what I expect.
Approach2:
numbers = ["SNID", "abc", "eee", "SNID", "abc"];
var list;
numbers.forEach(function(number) {
list = $(serial_list).find('li:not(.template)');
$(list).each(function(index, item) {
// console.log(number);
if (number == $(item).html()) {
$(item).remove();
return false;
}
});
});
The result is expected, but this kills the performance.
Why the approach1 does not work?
I am curious about removing return false
, since approach1 will work if the list have no duplicate item.
<ul id="serial_list" class="list-group scroll">
<li class="list-group-item template">template</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
<li class="list-group-item">eee</li>
<li class="list-group-item">fff</li>
<li class="list-group-item">ggg</li>
</ul>
Approach1:
numbers = ["SNID", "abc", "eee", "fff", "ggg"];
// find each li
var list = $(serial_list).find('li:not(.template)');
numbers.forEach(function(number) {
$(list).each(function(index, item) {
// console.log(number);
if (number == $(item).html()) {
$(item).remove();
return false;
}
});
});
In this case, approach1 will work as I expect. Why the return false
do not mess up in this case?
Thank you!
Upvotes: 2
Views: 234
Reputation: 24965
var numbers = ["SNID", "abc", "eee", "SNID", "abc"];
var $list = $('#serial_list').find('li:not(.template)');
$list.filter(function(){
return (numbers.indexOf(this.innerHTML) > -1);
}).remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="serial_list" class="list-group scroll">
<li class="list-group-item template">template</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
<li class="list-group-item">eee</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
</ul>
Upvotes: 0
Reputation: 497
HTML
<ul id="serial_list" class="list-group scroll">
<li class="list-group-item template">template</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
<li class="list-group-item">eee</li>
<li class="list-group-item">SNID</li>
<li class="list-group-item">abc</li>
</ul>
JavaScript
var numbers = ["SNID", "abc", "eee", "SNID", "abc"];
// find each li
var list = $('#serial_list').find('li:not(.template)');
list.each(function(index, elem) {
if (numbers.indexOf($(this).text()) != -1) {
$(this).remove();
}
});
Live Demo: http://jsfiddle.net/52Lckqob/
Upvotes: 0
Reputation: 30993
The return false
breaks the each loop iteration.
Ref:
We can break the $.each() loop at a particular iteration by making the callback function return false. Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
Remove it and will work fine.
Code:
numbers.forEach(function (number) {
$(list).each(function (index, item) {
if (number == $(item).html()) {
$(item).remove();
}
});
});
Demo: http://jsfiddle.net/IrvinDominin/zurkd3hq/
Upvotes: 4
Reputation: 2112
remove return false;
from Approach 1 and it will output as you want.
Upvotes: 0
Reputation: 133453
Since you are using $(item).remove();
you need to update the reference again in next iteration thus Approach 1 doesn't work
You can use filter()
along with indexOf
var list = $(serial_list).find('li:not(.template)');
list.filter(function(){
return numbers.indexOf($(item).html()) > -1;
//return $.inArray(numbers, $(item).html());
}).remove();
Upvotes: 1
Reputation: 74738
Can't just this has to be done:
$('#serial_list').find('li:not(.template)').remove();
instead of looping in the array.
Upvotes: 0