1

Working on a function that verifies if each number in an array is true or false and returns the first true number.

Have a working solution with a for loop as follows:

function findElement(arr, func) {
  var num;
  for (var a = 0; a < arr.length; a++) {
    if (func(arr[a])) {
      num = arr[a];
      return num;
    }
  }
  return num;
}

findElement([1, 3, 5, 8, 9, 10], function(num) {
  return num % 2 === 0;
})
// Should return 8

But I'm trying (in order to get my head around forEach better) to convert it into a forEach loop.

This is where I am so far, but I don't see how to actually return the num out of the loop after it's been established that the function result is true:

function findElement(arr, func) {
  if (arr.forEach(func) === true) {
    return num;
  }
}
findElement([1, 2, 3, 4], num => num % 2 === 0);
Rick
  • 4,030
  • 9
  • 24
  • 35
daggett
  • 239
  • 2
  • 4
  • 15
  • 1
    `var num; if (num = arr.find(func)) return num;` – Ele Jul 20 '18 at 16:55
  • 1
    `forEach` can't do an early return. – Evert Jul 20 '18 at 16:56
  • @Ele Ah I need to learn about .find - it looks perfect for this (alongside .filter(func)) but I was looking to learn about forEach! – daggett Jul 20 '18 at 16:57
  • So do you want an implementation of forEach ? – Prajval M Jul 20 '18 at 17:00
  • `forEach` is not always better than a "simple" `for`. That being said, `forEach` does not return anything, and it also ignores what the passed callback function returns. – ASDFGerte Jul 20 '18 at 17:00
  • 1
    @daggett `forEach` isn't a good choice for this particular problem. In fact, I rarely find it useful when working with arrays. [`map`, `filter`, and `reduce` can do most of the heavy lifting](https://zzzzbov.com/blag/functional-shape-of-loops), although there are a lot of other iterative patterns. Your function would probably be better written as `first([1, 2, 3, 4], num => num % 2 === 0)` which could take a predicate and return the first result that matches the predicate. – zzzzBov Jul 20 '18 at 17:00
  • @zzzzBov Right I see - so for this case the real problem is down to the fact that `forEach` just really isn't the one to use, but I still wonder if forEach can be made to work, just from an understanding of the method point of view – daggett Jul 20 '18 at 17:04
  • @daggett absolutely, if you used a `for` loop without a `break`, you could get it to work by setting a variable external to the loop. The exact same thing can be done with `forEach`. – zzzzBov Jul 20 '18 at 17:26

5 Answers5

1

Not sure how to use forEach but you could use array.prototype.filter:

function findElement(arr, func) {
  return arr.filter(func)[0];
}

@cdhowie suggested the use array.prototype.find in order to need the usage of [0].

function findElement(arr, func) {
  return arr.find(func);
}

Obviously, that is just a guess because it may raise an error if no item in the array meets the requirements of func.

If you still are looking about use forEach maybe you could do something like this:

function findElement(arr, func) {
  matches = []
  arr.forEach((item) => {
      if (func(item)) {
          matches.push(item)
      }
  });
  return matches[0];
}

Or:

function findElement(arr, func) {
  match = null
  arr.forEach((item) => {
     match = (match == null && func(item)) ? item : match
  });
  return match;
}

Again, you will have to check how to handle the error if no item in the array meets the requirements f your func.

Any of both codes produce

console.log(findElement([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; })))
8
Ender Look
  • 2,303
  • 2
  • 17
  • 41
1
function findElement(arr, func) {

    var num;

    arr.forEach(function(element) {
        if (!num && func(element)) {
            num = element;
          }
    });

    return num;
  }

For more options you can check this question: how to stop Javascript forEach?

Farooq Hanif
  • 1,779
  • 1
  • 15
  • 22
0

As has already been mentioned, this is not how forEach should be used.

However, you can still get the behavior you want:

function findElement(arr, func) {
  var num;

  arr.forEach(item =>{
    if (func(item)) {
      num = item;
      // .forEach does not have an early return
      // but you can force it to skip elements by removing them
      while (true) {
        // Remove all elements
        var removedItem = arr.shift();
        if (removedItem === undefined) {
          // All elements removed
          break;
        }
    }
  }
  return num;
}

This is even mentioned in the documentation

Vlad274
  • 6,514
  • 2
  • 32
  • 44
-1

maybe like this

function findElement(arr, func) {
  var num = null;

  for (var a = 0; a < arr.length && num === null; a++) {
    var val = arr[a];
    num = func(val) ? val : null; 
  }
  return num;
}

console.log(findElement([1, 3, 5, 8, 9, 10], function(num) {
  return num % 2 === 0;
}));
D. Seah
  • 4,472
  • 1
  • 12
  • 20
-1

here is your findElement method with foreach

function findElement(arr, func) {
var num = 0;

arr.forEach(function(item){
 if (func(item))
    return item;
  })
return num;
}
Code_Worm
  • 4,069
  • 2
  • 30
  • 35