0

Here is what I would like to do. However there's no "continue" inside a forEach.

    var que = null
    self.qs.forEach((q) => {
        if (q.synchronized == false) {
            que = q;
            break; // I would like to do this
        }
    });
    //  Now que would be set to the first not synchronized

Can anyone tell me how I can do this. Note that I am using the latest browsers. Please note I am only looking for one object in the array where synchronized == true. Sorry I used "continue" in my question earlier. The functionality I am looking for is "break".

3 Answers3

2

The MDN page on forEach has this to say:

Note: There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behaviour, the .forEach() method is the wrong tool, use a plain loop instead. If you are testing the array elements for a predicate and need a boolean return value, you can use every() or some() instead.

(my emphasis)

I think given your requirement of finding just the first entry, why not use just a plain loop:

var que = null
for (var i = 0; i < self.qs.length; i++)
{
    if (!self.qs[i].synchronized) {
        que = self.qs[i];
        break;
    }
}

Simple, straightforward and easy to understand exactly what's going on for future maintainers of the code. Just because we have fancy functions like forEach, some, reduce etc doesn't mean you have to use them in every single situation.

James Thorpe
  • 28,613
  • 5
  • 64
  • 82
1

Use Array.prototype.find();:

que = self.qs.find((q, i) =>  q.synchronized === true);

Description

The find method executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, find immediately returns the value of that element. Otherwise, find returns undefined. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.

var self = {
    "qs": [{
      synchronized: false,
      a: "b"
    }, {
      synchronized: true,
      xyz: "abc"
    }, {
      synchronized: true,
      xyz: "abc"
    }, {
      synchronized: true,
      xyz: "abc"
    }]
  },
  que = self.qs.find(function(q, i, arr) {
    console.log(i);
    return q.synchronized === true
  });

document.write(JSON.stringify(que, 0, 4));
Jai
  • 71,335
  • 12
  • 70
  • 93
0

you can use Array.prototype.some:

short form:

self.qs.some((q) => {
   return (q.synchronized == false) && (que = q, true);
});

or:

self.qs.some((q) => {
   if (q.synchronized == false)
   {
      que = q;
      return true;
   }
});

or:

self.qs.some(q => (q.synchronized == false) && (que = q, true));

Array.prototype.some returns on the first result that returns true.

Array.prototype.every returns on the first result that returns false.

They are basically tests for:

  • some: does at least 1 item return true
  • every: does every item return true

You can abuse this for something you want here :-)

The 3rd example is a bit of JS-fu but generates a nice oneliner ^_^

full code:

var que;
self.qs.some((q) => {
   if (q.synchronized == false)
   {
      que = q;
      return true;
   }
});
if (que) {
   // handle que here
}

Unoptimized dirty hack:

You could also use reduce for this:

var que = self.qs.reduce((result, q) => {
    if (que != null) return result;
    return (q.synchronized == false) ? q : result;
}, null);
// js-fu version
var que = self.qs.reduce((result,q) => que || (q.synchronized == false ? q : que),null);

Very unoptimized, but it saves you defining a var... It has no early out though.

DoXicK
  • 4,492
  • 22
  • 21
  • You mention "some: does at least 2 item return true". However what I am looking for is something that will only return 1 item. –  Feb 25 '16 at 11:06
  • `some` returns true or false. that's why you set `que = q` in it :-) also: `at least 1`. – DoXicK Feb 25 '16 at 11:07
  • Can you explain (que = q, true). I've never seen this before. Thanks –  Feb 25 '16 at 11:42
  • @Marilou It's the [comma operator](http://stackoverflow.com/questions/3561043/what-does-a-comma-do-in-javascript-expressions). – James Thorpe Feb 25 '16 at 11:43