user11679142
user11679142

Reputation:

JavaScript "If Statement" not returning true value

I have written a simple function that checks if the provided note is valid by looping over an array and comparing values.

The code always returns false and I am unsure why?

When I run the code item.split("/")[1] == note in isolation it returns true (with note = "C" ) so why is my function always returning false?

const chromatic = ["A", "A#/Bb", "B/Cb", "B#/C", "C#/Db", "D", "D#/Eb", "E", "E#/Fb", "F", "F#/Gb", "G", "G#/Ab"];

const isValidNote = (note) => {

  chromatic.forEach((item) => {
    if (item.split("/").length > 1) {

      console.log(item.split("/")[1] == note); // logs true on 3rd iteration

      if (item.split("/")[0] == note) return true;
      if (item.split("/")[1] == note) return true;
    } else if (item == note) {
      return true;
    }
  });
  return false;
}

console.log(isValidNote("C"));

Upvotes: 0

Views: 92

Answers (2)

Barmar
Barmar

Reputation: 781380

Returning from the forEach() callback just continues the loop, it doesn't return from the isValidNote() function.

Use some() instead of forEach(). It returns true if any of the callbacks return true.

You can also simplify the condition inside the callback, using includes().

const chromatic = ["A", "A#/Bb", "B/Cb", "B#/C", "C#/Db", "D", "D#/Eb", "E", "E#/Fb", "F", "F#/Gb", "G", "G#/Ab"];

const isValidNote = note => chromatic.some(item => item.split("/").includes(note));

console.log(isValidNote("C"));

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370889

forEach ignores any value returned by its callback. Use a for loop instead, so that return will return to the caller of isValidNote, instead of being ignored by forEach:

const chromatic = ["A", "A#/Bb", "B/Cb", "B#/C", "C#/Db", "D", "D#/Eb", "E", "E#/Fb", "F", "F#/Gb", "G", "G#/Ab" ];

const isValidNote = (note)=> {

    for (const item of chromatic) {
        if(item.split("/").length > 1){
            if(item.split("/")[0] == note) return true;
            if(item.split("/")[1] == note) return true;
        }
        else if(item == note){
            return true;
        }
    }
    return false;
}

console.log(isValidNote("C"));

Or, more concisely:

const chromatic = ["A", "A#/Bb", "B/Cb", "B#/C", "C#/Db", "D", "D#/Eb", "E", "E#/Fb", "F", "F#/Gb", "G", "G#/Ab" ];

const isValidNote = (note)=> {

    for (const item of chromatic) {
        const allNotes = item.split("/");
        if (allNotes.includes(note)) {
            return true;
        }
    }
    return false;
}

console.log(isValidNote("C"));

Or with .some:

const chromatic = ["A", "A#/Bb", "B/Cb", "B#/C", "C#/Db", "D", "D#/Eb", "E", "E#/Fb", "F", "F#/Gb", "G", "G#/Ab" ];

const isValidNote = note => chromatic.some(
  item => item.split("/").includes(note)
);

console.log(isValidNote("C"));

Upvotes: 2

Related Questions