1

I have something like this:

function myRatherLongFunction(){
    ... some computation ...
    var items = ... some array ...
    if (some condition) return something
    ... more computations ...
    if (some condition) return something
    ... more computations ...
    for (var i=0; i<items.length; i++){
        var item = items[i];
        var blah1 = ...something...
        var blah2 = ...something...
        var blah3 = ...something...
        if (loremIpsum(i,item,blah1,blah2,blah3)) {
            return someFunction(i,item,blah1,blah2,blah3);
        }
    }
    ... even more computations ...
}

Though I think (or feel) that .forEach is somewhat 'overhyped', I do like to use it, since it often saves typing, among other things. So, in above situation, how would I do that (talking about the for loop) with .forEach?

You see, if the items array has, say, 10 million entries, and I find something right at the beginning, I sure do not want to continue running a pointless search and make my code slow.

I know about Array.find and Array.findIndex, but they just return item or i, respectively.

I know I could throw an error (with message "item found") inside the .forEach callback function when the item is found, and then catch an error (with that same message) just outside the .forEach, but that all would be more typing than the straight for loop, so I do not want to do it that way. Any way this can be done with less typing (than straight for loop), not more?

Using .find or .findIndex, storing blah1 etc somehow, and retrieving the stored values after .find returns (so someFunction can be called thereafter) can certainly be made to work, but I doubt very much that that would be less typing compared to just keeping good old retro style.

UPDATE

Please consider Bergi's comment to be the accepted answer.

4
  • Your function does not what it says it does. It doesn't "find" the first item in an array. It looks for the first matching item, and returns the result of passing it (with some other params) to someFunction() and returns the result of this call as its own result. If you would separate the steps/concerns then you could definitely use .findIndex() (or .find() if you don't need the index).
    – Andreas
    Commented Jul 25, 2020 at 11:58
  • I still would separate the steps. Find the item that fulfills loremIpsum(), return it (its index), and then pass it to someFunction().
    – Andreas
    Commented Jul 25, 2020 at 12:04
  • separating steps is good. Keeping your code as short as possible is also good. Which one is "more important" is a matter of taste. It would bug me if I would have to cope with tons of JAVAesque ultra-verbose "filler code" just to separate steps. It's OK being less bugged by that than me, agree to disagree. Commented Jul 25, 2020 at 12:08
  • 1
    "hould I replace this for loop with a .forEach" - no, definitely not. Your feeling is correct. An early return from the loop is fine, just as you're doing early returns from other parts of the code.
    – Bergi
    Commented Jul 25, 2020 at 12:48

1 Answer 1

1

For me, this code is easier to understand (amount of typing is almost the same):

function findShoeSizeOfFirstItemSuchThat(items) {
  let blah1, blah2, blah3;
  let index = items.findIndex((item, index) => {
    blah1 = ...something...
    blah2 = ...something...
    blah3 = ...something...
    return loremIpsum(index, item, blah1, blah2, blah3)
  });
  if (index != -1) return someFunction(index, items[index], blah1, blah2, blah3);
}
1
  • 1
    Question updated. There is no findShoeSizeOfFirstItemSuchThat function in my original code. Obviously, you can't know that. My apologies for not putting the question as it is now right away. Commented Jul 25, 2020 at 12:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.