2

This is something I still don't quite understand very well, I have the following situation:

// #2) Check if this array includes any name that has "John" inside of it. If it does, return that 
// name or names in an array. 
const dragons = ['Tim', 'Johnathan', 'Sandy', 'Sarah'];

at first I tried the following:

const name = dragons.forEach(element => {
    element.includes("John") ? element : null
});

it returns undefined

then:

const name = dragons.filter(element => {
    element.includes("John");
});

it returns an empty array

then:

function name() {
    const dragons = ['Tim', 'Johnathan', 'Sandy', 'Sarah'];
    dragons.forEach(element => {
        if (element.includes("John")) {
            return element;
        }
    });
}

again it returns undefined

but the interesting thing is that if on any of the attempts I change the action to do to console.log(element); then it will show "Johnathan" which is the correct output.

so it means that the logic is working, I just don't understand why it won't return the value if I want to let's say assign it to a variable.

I even tried the following:

const dragons = ['Tim', 'Johnathan', 'Sandy', 'Sarah'];

dragons.forEach(element => {
    if (element.includes("John")) {
        const name = element;
    }
});

but it again returns name as undefined, why is that?

edit: this was my first stack overflow question, really I wasn't expecting someone answering my question, I thought maybe it was a dumb question or that i didn't explained myself well but it was very nice to find such a supportive community, thank you so much to all of you who commented and helped me!

diegossn
  • 31
  • 4
  • Things will become easier when you grasp the difference between `element => { element.includes("John"); }` and `element => element.includes("John")`. One of the two works, the other doesn't. – Wiktor Zychla Oct 31 '22 at 19:48
  • 1
    "*at first I tried the following*" `forEach` always returns `undefined`. Even if you return a value in the callback, which you don't. For the second attempt see: [When should I use a return statement in ES6 arrow functions](https://stackoverflow.com/q/28889450). For the third: [Function with forEach returns undefined even with return statement](https://stackoverflow.com/q/16392445). For the fourth: [What is the scope of variables in JavaScript?](https://stackoverflow.com/q/500431). – VLAZ Oct 31 '22 at 19:49
  • You are reinventing `some()` or `every()` – epascarello Oct 31 '22 at 19:55
  • Ohh, I tried: ```const name = dragons.filter(element => element.includes("John"));``` and now it outputs the correct result, so the mistake was to include the curly brackets and the ; after the statement? thank you so much @WiktorZychla for clarifying! – diegossn Oct 31 '22 at 19:56
  • return an array of `["John", "John", "John"]` or?... Could you explain your exact task? – Roko C. Buljan Oct 31 '22 at 19:56

2 Answers2

3

forEach method does return undefined. But filter instead returns the array but filtered. However, the problem is that you are forgetting to return the values inside it.

To fix it try:

const name = dragons.filter(element => {
  return element.includes("John");
});

Or:

const name = dragons.filter(element => element.includes("John"));
  • the method "includes" is not defined on element, which is a string. It is defined only on the array. so it should rather be `filter(element => element == "John")` – Sebastian Oct 31 '22 at 19:51
  • 1
    @Sebastian "*the method "includes" is not defined on element, which is a string.*" https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes ??? – VLAZ Oct 31 '22 at 19:53
  • 1
    `includes` is a method of the `String`. Also, if you check `element == "John"` would be incorrect because we want to check a subtring inside a `string` – Franco Agustín Torres Oct 31 '22 at 19:54
  • Oh, double sorry, both your comments are correct, my bad. – Sebastian Oct 31 '22 at 19:55
  • it seems that I was missing the return keyword on the filter method, I forgot I had to use it I thought it automatically returned if the condition resolved to true. thank you so much! now I understand. – diegossn Oct 31 '22 at 20:10
2

First, forEach never returns anything. You'd need a map for that, or filter (what are you exactly after?). Second, your callback functions don't return anything, either. You can map or filter your array like that:

const dragonsNamedJohn = dragons.filter(name => name.includes('John'));

or

const dragonsNamedJohn = dragons.filter(name => {
    return name.includes('John'); 
});

or even

function hisNameIsJohn (name) {
    return name.includes('John');
}

const dragonsNamedJohn = dragons.filter(hisNameIsJohn);

(You might want to stick toLowerCase() somewhere there, or not, dependent on whether you want the comparison to be case-sensitive. Also, another way of skinning a dragon would be to use a regular expression).

VLAZ
  • 26,331
  • 9
  • 49
  • 67
mbojko
  • 13,503
  • 1
  • 16
  • 26
  • These solutions compare only the entire `string`, they do not check if a value is inside a `string`, so they are not the correct solutions. – Franco Agustín Torres Oct 31 '22 at 19:52
  • But... the task is to return an Array (of all the names) - if "John" was not found. Otherwise, return the String "John"? OR I misunderstood... perhaps the task if to return `["John", "John", "John"]` if multiple "John" are present in the original Array...? – Roko C. Buljan Oct 31 '22 at 19:52
  • Thank you for the other ways to solve the problem, I understand now that I must use the return keyword if I'm using the curly brackets inside the arrow function in the method, I was confused, thank you for clarifying! – diegossn Oct 31 '22 at 20:16