omg
omg

Reputation: 139862

How to catch last iteration inside $.each in jQuery?

var arr = {'a':fn1,'b':fn2,'c':fn3}

$.each(arr,function(name,func){
(do something particular for the last iteration)
...
})

It'll be best if no additional variables are used.

EDIT: I mean LITERALLY last one,which is the last pair I type them.

Upvotes: 19

Views: 27214

Answers (6)

balanza
balanza

Reputation: 1079

Here I propose a brand new, improved answer.

An elegant way could be using a after() function wrapper. Here's the code:

function after(fn, times){
   return function(){
     if(--times === 0){
       var args = Array.prototype.slice.call(arguments);
       fn.apply(this, args);
     }
   };
 }

fn is the function you want to be executed at last, times is the number of different response you are waiting for.

after() wraps your function and creates a new function that runs its code only after times calls. Here's an example in brief:

function onLastResponse(foo){
  console.log('this is last iteration');
}

var myCallback = after(onLastResponse, 3);

myCallback(); //not executed
myCallback(); //not executed
myCallback(); //executed

Check this jsbin for a live example: https://jsbin.com/sufaqowumo/edit?js,console

Upvotes: 0

balanza
balanza

Reputation: 1079

Being jQuery.each function syncronous, do you really need to track last iteration? Just put your code after the $.each() call.

Upvotes: -2

Caleb Wright
Caleb Wright

Reputation: 164

If you need something to happen, say you are iterating over a single list and you wanted another object to be inserted conditionally but if the condition is not met you need it to be inserted last, you can do something like:

$list = $({{some_selector}});
$list_elt = $({{some_html}})
$list.each(function (i) {
    if ({{condition is met}}) {
         $(this).before($list_elt);
         return false;
    }
    else if (i == $list.length - 1) {
        $(this).after($list_elt);
        return false;
    }
});

which is the same thing as Philippe's solution, really. If there is some reason this should not work, please comment and let me know, because I use it.

Upvotes: 1

Alex Barrett
Alex Barrett

Reputation: 16455

Now that I have seen your duplicate question - where you state, "For the following,it's 'c':fn3" - it seems you might be after the value of the maximum property of an object.

var obj = { 'a': fn1, 'b': fn2, 'c': fn3 };

var maxKey;
for (var key in arr) {
    if (!(maxKey > key)) {
        maxKey = key;
    }
}

// fn will be fn3
var fn = obj[maxKey];

Upvotes: -2

Alex Barrett
Alex Barrett

Reputation: 16455

Philippe Leybaert's answer outlines the problems with your question very well, and there is probably a clearer way of doing what you want. But that said, I cannot see a way to do what you ask without using an extra variable.

var obj = { 'a': fn1, 'b': fn2, 'c': fn3 };
var lastKey;

$.each(obj, function(key, fn) {
    // do stuff...
    lastKey = key;
});

obj[lastKey].doStuffForLastIteration();

Upvotes: 4

Philippe Leybaert
Philippe Leybaert

Reputation: 171764

Your example variable is called 'arr', but it's not an array at all (it's an object). This makes it a little confusing.

When iterating over an object, there's no such thing as a "last" property, because the order of properties is undefined by design.

When iterating over an array, you can simply compare the first parameter of the callback with the (array.length-1) to detect the last iteration.

In code (for arrays):

var arr = [ "a","b","c" ];

$.each(arr, function(i,val) { if (i == arr.length-1) ... });

Upvotes: 33

Related Questions