1

I'm learning javascript and I have a problem I stumbled upon. I have the following javascript code (I'm searching for the name john inside MyArray, which contains class objects):

MyArray.forEach(
  (v,i)=>(
    v.name == 'john' && return i
  )
);

This is not working, because I get the following error for the 3rd line:

SyntaxError: expected expression, got keyword 'return'

My question is, how can I put statement inside an expression?

eisbehr
  • 12,243
  • 7
  • 38
  • 63
Borneyak
  • 47
  • 1
  • 8
  • 2
    Returning wouldn't help you there. Look at [Array.prototype.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) – Denys Séguret Apr 06 '18 at 12:23
  • why do you need a return value for [`Array#forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) (which does not respect it), btw, it should work without return statement in an [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) – Nina Scholz Apr 06 '18 at 12:23

4 Answers4

2

Looks like you want to find the index of the Mr. John? Then use dedicated method findIndex for this:

const john = MyArray.findIndex(
  (v,i) => (
    v.name == 'john'
  )
);
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • 1
    Don't you think you should have closed here ? – Denys Séguret Apr 06 '18 at 12:25
  • @DenysSéguret Ah, you mean duplicate. Well it's possibility, but in this case I preferred to answer. – dfsq Apr 06 '18 at 12:26
  • Yes, I meant as duplicate. But I guess the odd way the question was asked led you to think about it before you noticed it was just a common one, behind the XY one. – Denys Séguret Apr 06 '18 at 12:29
  • Could be a bit more handy imo: `MyArray.findIndex(v => v.name == 'john')` ;) – eisbehr Apr 06 '18 at 12:29
  • *"My question is: How can i put statement inside an expression?"* This answers the *example*, not the question. (The example is already answered [elsewhere](https://stackoverflow.com/questions/7364150/find-object-by-id-in-an-array-of-javascript-objects).) – T.J. Crowder Apr 06 '18 at 12:34
  • @eisbehr of course. but i just kept style OP prefers. – dfsq Apr 06 '18 at 12:35
  • 1
    @T.J.Crowder I don't think OP really wants statement inside expression, they probably just doesn't know that forEach is not the way to go. – dfsq Apr 06 '18 at 12:36
2

How can i put statement inside an expression?

You can't, currently. Nor, in that example, do you want to. The return value of the forEach callback isn't used for anything.

See below the horizontal rule for your specific case, but answering the question you actually asked:

On occasion, wanting to do some statement logic and then have an overall expression take the final result of that statement logic does come up. Consequently, there's a proposal for do expressions working its way through the JavaScript proposals process. It's only at Stage 1 of the process, and so it may not progress, or if it progresses the form of it may change, but for now it looks like this:

let x = do {           // Using the `do` expression proposal
  let tmp = f();       // (currently just Stage 1, do not use!)
  tmp * tmp + 1
};

...where x would get the result of that last expression within the {}.

If you really wanted to do that now, you'd probably use an immediately-invoked arrow function:

let x = (() => {
  let tmp = f();
  return tmp * tmp + 1;
})();

The purpose of do expression proposal is to make that less verbose, when you need to do.

(Please don't mistake this for my offering an opinion on do expressions either way. I'm just noting the proposal exists and is working through the process.)


Your specific case of finding the index of an item:

In your specific case, you're looking for the Array#findIndex function, which returns the index of the entry where the callback returns a truthy value:

const index = MyArray.findIndex(v => v.name == 'john');

(Or you might want Array#find if you want the entry itself instead of its index.)

Note that since that uses a concise arrow function, the return value of the function is the value of the expression forming the function body. We could use a verbose one instead with an explicit return:

const index = MyArray.findIndex(v => { return v.name == 'john'; });
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You cant. Just do:

 for(const [index, el] of myArray.entries())
   if(el.name === "john") return index;

Or more easy:

  return myArray.findIndex(el => el.name === "john");
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • *"My question is: How can i put statement inside an expression?"* This answers the *example*, not the question. (The example is already answered [elsewhere](https://stackoverflow.com/questions/7364150/find-object-by-id-in-an-array-of-javascript-objects).) – T.J. Crowder Apr 06 '18 at 12:34
0

forEach is just a loop of all elements. You can't return anything there like you did. You could use find for example, if you want the object with the name john:

var MyArray = [
  {name: 'test', some: 'data'},
  {name: 'john', some: 'data'},
];

var obj = MyArray.find(v => v.name == 'john');

console.log(obj);
eisbehr
  • 12,243
  • 7
  • 38
  • 63
  • *"My question is: How can i put statement inside an expression?"* This answers the *example*, not the question. (The example is already answered [elsewhere](https://stackoverflow.com/questions/7364150/find-object-by-id-in-an-array-of-javascript-objects).) – T.J. Crowder Apr 06 '18 at 12:34
  • Well, I said he can't. ;) @T.J.Crowder – eisbehr Apr 06 '18 at 12:36