Michael Wilson
Michael Wilson

Reputation: 1915

Lodash how to short circuit terminate

Is there a way to have Lodash terminate early such that this returns true instead of throwing exception?

_.chain([i => 'a', 0])
.reduce((prev, curr) => prev.concat(curr()), [])
.some(i => i == 'a')
.value()

Upvotes: 0

Views: 656

Answers (4)

skyboyer
skyboyer

Reputation: 23705

You are asking for lazy evaluation. It exists for some methods that are listed in docs for lodash wrapper - check .some is not chainable by default.

Also reduce() cannot be lazy evaluated since reduce() may/can/will affect all the its result at each step(or am I wrong on that point?).

_([(i) => 'a', 0])
  .map(x=> x())
  .filter(x => x === 'a')
  .slice(0, 1)
  .value()

works almost as you asked(except that fact .slice returns undefined instead of boolean False in case there was no such an element)

Upvotes: 0

Markus
Markus

Reputation: 1636

Yes, use transform instead of reduce.

Iteratee functions may exit iteration early by explicitly returning false.

https://lodash.com/docs/4.17.5#transform

Upvotes: 0

Michael Wilson
Michael Wilson

Reputation: 1915

I believe actually I'm thinking about the problem incorrectly, if the answer I'm wanting is the boolean result of .some(), then that should be my highest order query.

_.chain([i => 'a', 0])
.some(i => i() == 'a')
.value();

Then it evaluates the first item first and quits early. Expecting a Lodash specific answer is non-useful.

Upvotes: 1

Nicolas Gehlert
Nicolas Gehlert

Reputation: 3253

First of all your code is really hard to read and the use of _.chain is not really needed.

Your functions throws an error because you try to call a function on your second entry in the array with curr().

Everything you want to achieve in your result you can do without lodash.

const values = [i => 'a', 0];

const filtered = values.reduce((prev, curr) => {
  if (typeof curr === 'function') {
    prev.push(curr());
  } else {
    prev.push(curr);
  }

  return prev;
}, []);

const hasSpecificValue = filtered.some(i => i == 'a');

console.log(hasSpecificValue);

Here I added a jsfiddle for example

https://jsfiddle.net/fhk7q0uf/6/

If you just want to fix your code, either remove the 0 entry or add a separate check to the reduce function. Could look like this

_.chain([i => 'a', 0])
.reduce((prev, curr) => prev.concat(typeof curr === 'function' ? curr() : curr), [])
.some(i => i == 'a')
.value()

Upvotes: 0

Related Questions