Mike Rifgin
Mike Rifgin

Reputation: 10745

get a total of jquery's .each()

I'm using jquery's .each() to iterate over a group of li's. I need a total of all the li's matched. Is the only way to create a count variable outside the .each() and increment this inside the .each()? It doesn't seem very elegant.

var count;
$('#accordion li').each(function() {
    ++count;
});  

Upvotes: 35

Views: 63666

Answers (6)

Tho
Tho

Reputation: 25070

You can try this

const count = $('#accordion li').each(function() {
    // Do something
}).length;

It works because .each() returns a jQuery object which has a length property.

Upvotes: 1

Brad Hobson
Brad Hobson

Reputation: 3

One of the big issues, which I have not found a fix for yet, is if you have two sets of the same thing you will iterate through.

For instance, 2 table heads that you are iterating through number of column headers. If you use length on ( $item.children().find('thead tr th').each... ) for your each clause and you have 2 tables it will double the amount of your length that you are trying to walk through potentially [5 column headers in each table will return length of 10].

You could do both on a id name and have those different but if adding dynamically then this can become a headache.

The only way I found once inside the foreach is to use $(this):

$item.children().find('thead tr th').each(function(i, th) {
  // I am working with a table but div could be used, or something else. 
  // I have 2 tables with 5 column headers, the below len return
  var len = $(this).closest('table').find('thead tr th').length;
  if (i < len) {
    // ...your code here
  }
});

Upvotes: 0

Owen
Owen

Reputation: 84503

Two options:

$('#accordion li').size(); // the jQuery way
$('#accordion li').length; // the Javascript way, which jQuery uses

Since jQuery calls length under the hood, it's faster to use that instead of the size() call.

Upvotes: 65

Arron
Arron

Reputation: 787

Ok so the best way to do this is as follows: firstly map the wrapped set to a variable so you never have to do the sizzle dom lookup again:

var $myListItems = $('#accordian li');

Note: my preference is to put $ at the beginning of any vars that are a jQuery wrapped set, hence $myListItems as opposed to myListItems

Then set a var outside the each function that has the length of the wrapped set:

var myLength = $myListItems.length;

Note the lack of a $ here as the var is not a jQuery object.

Now run the each function with a variable for the index.

$myListItems.each(function(index){
    // myLength has the length
    // index has the current, 0 based index.
});

You now have what you've asked for in the OP with only one look up and so need to fumble in the each function with having to know the contents of the wrapped set just to know the length of it. the beauty of this over a counter is that on every iteration of the each you already know the length.

Upvotes: 2

user113716
user113716

Reputation: 322492

Well, I just saw this question, and you already accepted an answer, but I'm going to leave one anyway.

The point of the question seems to be concerned with incrementing a counter.

The fact is that jQuery's .each() method takes care of this for you. The first parameter for .each() is an incrementing counter, so you don't need to do it yourself.

$('#accordian li').each(function(index) {
       // index has the count of the current iteration
    console.log( index );
});

So as you can see, there is an elegant solution built in for you.

Upvotes: 9

Colin Brock
Colin Brock

Reputation: 21565

$('#accordion li').length;

Upvotes: 8

Related Questions