Функция с вложенным forEach и для l oop не вернет false - PullRequest
4 голосов
/ 04 апреля 2020

Я выполняю алгоритм вызова для практики в JS. У меня есть программа, которая запускается через al oop, и когда условие выполнено, функция должна вернуть false. Однако, когда условие выполнено, возврат не работает, и функция всегда заканчивается возвращением true.

const isDiagonalLeftWristband = (band) => {
  band.forEach((row, y) => {
    row.forEach((item, x) => {
      for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++) {        
        if (band[y][x] !== band[y+i][x+i]) {
          console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
          return false;
        }
      }
    })
  })
  return true;
}


const band3 = [
  ["A", "B", "C"],
  ["C", "Z", "B"],
  ["B", "C", "A"],
  ["A", "B", "C"]
];

console.log(isDiagonalLeftWristband(band3))

Вывод:

false //from console log
false //from console log
true //from function return statement

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

2 голосов
/ 04 апреля 2020

return false будет выходить только из анонимной функции (item, x) => {}, а не isDiagonalLeftWristband(), как вы ожидаете. После выполнения двух forEach isDiagonalLeftWristband() всегда будет return true в конце. Вы можете использовать циклы, чтобы избежать этой проблемы.

const isDiagonalLeftWristband = (band) => {
  for (let [y, row] of band.entries()) {
    for (let [x, item] of row.entries()) {
      for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++) {        
        if (band[y][x] !== band[y+i][x+i]) {
          console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
          return false;
        }
      }
    }
  }
  return true;
}

const band3 = [
  ["A", "B", "C"],
  ["C", "Z", "B"],
  ["B", "C", "A"],
  ["A", "B", "C"]
];

console.log(isDiagonalLeftWristband(band3))

forEach не предназначен для досрочного прекращения. Он всегда будет перебирать все элементы. (это во имя :)). Из документации MDN:

Нет способа остановить или прервать forEach () l oop, кроме как с помощью исключения. Если вам нужно такое поведение, метод forEach () является неправильным инструментом.

Раннее завершение может быть выполнено с помощью:

A simple for loop
A for...of / for...in loops
Array.prototype.every()
Array.prototype.some()
Array.prototype.find()
Array.prototype.findIndex()

Методы массива: every (), some (), find () и findIndex () проверяют элементы массива с помощью предиката, возвращающего истинное значение, чтобы определить, требуется ли дальнейшая итерация.

Вместо этого можно использовать одну из предложенных функций, предназначенных для проверки элементов массив с предикатом. every() проверяет, проходят ли все элементы массива какой-либо тест; что, по крайней мере, семантически, то, что вам нужно.

const isDiagonalLeftWristband = (band) => {
  return band.every((row, y) => {
    return row.every((item, x) => {
      for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++) {        
        if (band[y][x] !== band[y+i][x+i]) {
          return false;
        }
      }
      return true;    
     });
  });
}

const band3 = [
  ["A", "B", "C"],
  ["C", "B", "B"],
  ["B", "C", "A"],
  ["A", "B", "C"]
];

console.log(isDiagonalLeftWristband(band3))
0 голосов
/ 04 апреля 2020

статистические данные return false; возвращают только значение функции, к которой он принадлежит, а это

(item, x) => {
      for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++) {        
        if (band[y][x] !== band[y+i][x+i]) {
          console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
          return false;
        }
      }
    }

ваш код должен работать так, чтобы он мог возвращать ложное значение основной функции, вы можете используйте этот подход:

const isDiagonalLeftWristband = (band) => {
  let returnValue = true;
  band.forEach((row, y) => {
    row.forEach((item, x) => {
      for(let i = 0; (i < band[y].length - x) && (i < band.length - y); i++) {        
        if (band[y][x] !== band[y+i][x+i]) {
          console.log(false) //FALSE GETS OUTPUTTED MULTIPLE TIMES
          returnValue = false;
          // return false;
        }
      }
    })
  })
  return returnValue;
}

То, что предложил domondo, намного лучше, потому что функция существует, когда она находит первое false

...