0

I am having a lot of trouble with the syntax and application of forEach functions. Please help!

Recreate the function droids from the previous challenge, but instead of using a FOR loop, use the built-in forEach method.

Previous challenge:

function droids(arr) {
  let result = '';
 for (let str of arr) {
      if (str  === 'Droids') {
       return 'Found Droids!';
    }
}
       return `These are not the droids you're looking for.`;
}


// Uncomment these to check your work! 
const starWars = ["Luke", "Finn", "Rey", "Kylo", "Droids"] 
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"] 
console.log(droids(starWars)) // should log: "Found Droids!"
console.log(droids(thrones)) // should log: "These are not the droids you're looking for."

This is what I have:

function droids(arr) {
  let result = "";
arr.forEach(item => 
console.log(result))
if (result = "Droids") {
return "Found Droids!"
} else {
  return "These are not the droids you're looking for.";
}};
John Belknap
  • 15
  • 1
  • 4
  • 1
    You can't use `foreach` to return from an outer function, so it isn't a good fit here. `foreach` should really be used when you just want to carry out simple side effects over a list, like printing or modifying an outer state. – Carcigenicate May 11 '21 at 13:54
  • find() or indexOf() are better suited here – bel3atar May 11 '21 at 13:54
  • 1
    Proper indentation would make this so much more readable – Andreas May 11 '21 at 13:55
  • Don't just swap operators... `=` should be `==` or `===` – Andreas May 11 '21 at 13:56
  • Why is the `return "These are not..."` _in_ the loop? – Andreas May 11 '21 at 13:56
  • The only way I can think of is before set the forEach loops, let found = false; Then set it found = true in the forEach if the condition is met. As others have said there are better ways than using forEach, I wonder if that’s the point of the challenge. – Andrew May 11 '21 at 14:01
  • Whoever marked this as duplicate is a bit off here with the linked question. There's more than just breaking out of a forEach loop going on here. – daddygames May 11 '21 at 14:09
  • Yeah, the linked dup is *a* possible solution, but this is certainly a distinct question from that one at least. – Jacob G May 11 '21 at 14:17

4 Answers4

1

You can't return a value from the callback in a forEach loop, so you need to rely on side effects - give result a default value indicating you didn't find Droids and then set it to "Found Droids!" only if you do match Droids somewhere in the array:

function droids(arr) {
  let result = "These are not the droids you're looking for.";
  arr.forEach(item => {
    if (item === "Droids") {
      result = "Found Droids!";
    }
  });
  return result
}

// Uncomment these to check your work! 
const starWars = ["Luke", "Finn", "Droids", "Rey", "Kylo"]
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"]
console.log(droids(starWars)) // should log: "Found Droids!"
console.log(droids(thrones)) // should log: "These are not the droids you're looking for."
Nick
  • 138,499
  • 22
  • 57
  • 95
0

if (result = "Droids") This does not check, it assigns. You want to use ==.

You don't want to return from inside the forEach method. You need to assign the result and return that result after processing the records.

Be sure to compare the item to the string value you're looking for.

function droids(arr) {
  let result = "";
  let foundDroids = false;
  arr.forEach(item => {
    if (!foundDroids) {
      if (item == "Droids") {
        result = "Found Droids!"
        foundDroids = true;
      } else {
        result = "These are not the droids you're looking for.";
      }
    }
  });
  return result;
};

const starWars = ["Luke", "Finn", "Droids", "Rey", "Kylo"] 
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"] 
console.log(droids(starWars)) 
console.log(droids(thrones))

I would prefer to use Array.includes like so:

function droids(arr) {
  if (arr.includes("Droids")) {
    return "Found Droids!";
  } else {
    return "These are not the droids you're looking for.";
  }
};

const starWars = ["Luke", "Finn", "Droids", "Rey", "Kylo"] 
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"] 
console.log(droids(starWars)) 
console.log(droids(thrones))
daddygames
  • 1,880
  • 1
  • 11
  • 18
0

I would just not use Array.prototype.forEach, but instead use Array.prototype.some to determine whether the item was present or not.

The some has the same signature as the forEach method, except you need to return a boolean. If you return true, the method will short-circuit and stop iteration immediately upon finding a match. It is better for performance.

const search = (items, target, foundText, notFoundText) =>
  items.some(item => item === target) ? foundText : notFoundText;

const droids = (names) => search(names, 'Droids', 'Found Droids!',
  "These are not the droids you're looking for.");

// Uncomment these to check your work! 
const starWars = ["Luke", "Finn", "Rey", "Kylo", "Droids"]
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"]
console.log(droids(starWars)) // "Found Droids!"
console.log(droids(thrones))  // "These are not the droids you're looking for."

Since this is a primitive array, you could also use Array.prototype.includes.

const search = (items, target, foundText, notFoundText) =>
  items.includes(target) ? foundText : notFoundText;

const droids = (names) => search(names, 'Droids', 'Found Droids!',
  "These are not the droids you're looking for.");

// Uncomment these to check your work! 
const starWars = ["Luke", "Finn", "Rey", "Kylo", "Droids"]
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"]
console.log(droids(starWars)) // "Found Droids!"
console.log(droids(thrones))  // "These are not the droids you're looking for."
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • Not sure how well this answers the question, as OP was specifically asking how to do it with `forEach` – Jacob G May 11 '21 at 14:05
  • @JacobGray The method `Array.prototype.some` method is a modified version of `Array.prototype.forEach` that expected a boolean return value that can short-circuit if the return value is `true`. I updated the response to include a blurb. – Mr. Polywhirl May 11 '21 at 14:07
  • My point more being that this appears to be a homework-style question, and if he were to use `some` or `includes`, he'd risk failing. Not sure how a question like this should be treated though. – Jacob G May 11 '21 at 14:11
0
function droids(arr) {
  let result = '';
  arr.forEach(item => {
    item === "Droids" ? result = `Found Droids!` : result = `These are not the droids you're looking for.`
  });
  return result;
}

const starWars = ["Luke", "Finn", "Rey", "Kylo", "Droids"]
const thrones = ["Jon", "Danny", "Tyrion", "The Mountain", "Cersei"]
console.log(droids(starWars)) // should log: "Found Droids!"
console.log(droids(thrones)) // should log: "These are not the droids you're looking for."
bryanpsd
  • 33
  • 7