-1

I'm trying to return a value inside a map function before reaching the default return value at the end of the function.

I noticed the map function is not returning a value for the validateSequence function, but a simple for loop can.

function validateSequence(sequence) {

  const modifers = ['-', 'm', 'b', 'i'];

  sequence.map((seq) => {
    if(!modifers.includes(seq)) {
      return false; // want to return false
    };
  });

  return true;
};


validateSequence(['Z','e','p']); // returns true
function validateSequence(sequence) {

  const modifers = ['-', 'm', 'b', 'i'];

  for(let i=0; i<sequence.length; i++) {
    if(!modifers.includes(sequence[i])) {
      return false;
    };
  };

  return true;
};


validateSequence(['Z','e','p']); // returns false

I expect the map function to return false before it reaches the default return value, true. I know that the map function is executed before reaching the default return value true, so why isn't it returning false?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
David
  • 303
  • 3
  • 8
  • 21
  • 2
    The map function is returning seomething, but you do not do anything with it. – Marco May 05 '19 at 07:01
  • map iterates over every item in the array and builds a new array of the return values from the callback (in your case, false and undefined. It won't stop early unless the callback throws an error. It's not the right tool for the job; just use the for loop. – jonrsharpe May 05 '19 at 07:20

6 Answers6

3

Here:

sequence.map((seq) => {
  if (!modifers.includes(seq)) {
    return false; 
  };
});

You are returning false from the (seq) => {} provided callback and not the validateSequence function itself. You can't break from map or forEach methods. So, a for loop is a better option here.

You could also check if every item in sequence is present in modifers like this:

function validateSequence(sequence) {
  const modifers = ['-', 'm', 'b', 'i'];
  return sequence.every(letter => modifers.includes(letter))
};

console.log(validateSequence(['Z','e','p']))
console.log(validateSequence(['m', 'i']))
adiga
  • 34,372
  • 9
  • 61
  • 83
1

There's several problems here:

  1. Modifier is misspelled as modifer.
  2. The two examples you posted are not the same. In the map() version, that callback you're passing in is being used to return a new value which is going to be in the return of the map() function. When you return false in that callback, you're not returning out of validateSequence(), you're returning out of the callback (which puts false in the return result of map).

You can see this below:

function validateSequence(sequence) {

  const modifers = ['-', 'm', 'b', 'i'];

  const test = sequence.map((seq) => {
    if(!modifers.includes(seq)) {
      return false; // want to return false
    };
  });

  console.log(test); // [false, false, false], this is where your return false is going.

  return true;
};
Jay
  • 61
  • 1
0

Map is returning false, for each element in your sequence variable. So if you return that, you'd end up with an array of false elements:

function validateSequence(sequence) {
  const modifers = ['-', 'm', 'b', 'i'];
  return sequence.map((seq) => {
    if(!modifers.includes(seq)) {
      return false; // want to return false
    };
  });
};

Calling validateSequence(['Z','e','p']) will then result in [false, false, false]

Of course, if you store the result of map in a variable, you could the evaluate that, to determine if all, some, any are false if you so like. That is up to you.

Marco
  • 22,856
  • 9
  • 75
  • 124
0

.map creates a new array with the results of calling a provided function on every element in the calling array. It isn't a substitute for a loop.

What you are actually doing is creating an array of booleans, but not storing it regardless. So it then finishes that task, then returns true at the bottom.

Try using .forEach, if you wish to iterate over the array or perhaps using .every, which will simplify your logic:

function validateSequence(sequence) {
  const modifers = ['-', 'm', 'b', 'i'];
  return sequence.every(letter => modifers.includes(letter))
};
user2340824
  • 2,142
  • 2
  • 15
  • 19
0

In your validateSequence function at the end you have return true that's why you always get true. If you want to return result of map then add return to it.

return sequence.map((seq) => {
    if(!modifers.includes(seq)) {
      return false; // want to return false
    } else {
      return true;
    }  
 });

I'am not sure what you want the result, but if you want to break the loop if certain condition passes, then this will not serve your purpose because map always returns a value, it a one-to-one mapping. If you want to break a loop, you simple for loop.

random
  • 7,756
  • 3
  • 19
  • 25
0

You can do this

function validateSequence(sequence) {

    const modifers = ['-', 'm', 'b', 'i'];

    const isMatch = sequence.some(seq => {
        return modifers.includes(seq)
    })

    return isMatch
}
console.log(validateSequence(['Z', 'e', 'p']))
Shuvro
  • 222
  • 3
  • 7