9

I have a method which returns a value from an element in the array. Not all the elements have the property I want to return. I would like to do this function with one line using the method find(). I've tried this way to solve it:

getExecsFromTour(tourId){
 return this.repInfo.find(el => el.id == tourId ).execs || [];
}

But the elements which don't contain the property execs return an error of undefined.

To solve it, I had to store the result in a local variable:

getExecsFromTour(tourId){
    let items       = this.repInfo.find(el => el.id == tourId);
    return items    != undefined ? items.execs : [];
}

But I would like to know if I am missing something and this function can be achieved with one sentence.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Joan
  • 233
  • 1
  • 5
  • 17
  • 4
    If you really need this to be one line, you can use `(this.repInfo.find(el => el.id == tourId) || {}).execs || [];` – Titus Sep 18 '18 at 15:18
  • 3
    There is no harm in making things readable on multiple lines.... – epascarello Sep 18 '18 at 15:22
  • Hello! Thanks @Titus, I totally forgot the `{}`statment >.<. @epascarello You're right, but I was curious about how to solve this, because it might help me in the future! – Joan Sep 18 '18 at 15:24

2 Answers2

13

You seem to have the general idea, Array.prototype.find will search the array for the first element which, when used as an argument of the callback, will have the callback return a truthy value. If nothing is found, it returns undefined.

Your code should work, but yes, one way to do it in one line (if you want) is to use:

getExecsFromTour(tourId){
  return (this.repInfo.find(el => el.id == tourId) || {}).execs || [];
}

If Array.prototype.find returns undefined, the first inner parenthetical expression will be evaluated to empty object, which can attempt (and fail) to access the .execs key without a TypeError, which will also evaluate to undefined, in which case the function returns empty array, which is what your code above does.

EDIT: Someone commented this solution already, lol, but as the comments say, nothing wrong with keeping it multiline (more readable that way).

DCtheTall
  • 176
  • 2
  • 7
  • 1
    Hello! Yes, somebody before answer this, but none with your explication. Thank you so much! – Joan Sep 18 '18 at 15:41
-1

what about

getExecsFromTour(tourId){
     return this.repInfo.find(el => 'execs' in el && el.id == tourId ).execs || [];
}

...

EDITED

var a = [{execs : 1, id:4}, {id:5}];
function getExecsFromTour(tourId, x){
    return (x = a.find(el => 'execs' in el && el.id == tourId )) ? x.execs : [];
}

this time at least I ran it couple of times

fedeghe
  • 1,243
  • 13
  • 22