Код застревает где-то в последовательности циклов for, и я не знаю почему - PullRequest
0 голосов
/ 22 января 2019

РЕДАКТИРОВАТЬ - я изменил код для правильного объявления переменных ниже, но, кажется, ничего не изменилось

Я написал код с использованием цикла for, который должен удовлетворять ряду критериев, прежде чем выполнять то, что в нем.Проблема заключается в том, что где-то по пути код застревает внутри одного из циклов, вызывая сбой компьютера.

Я попытался разорвать цикл, но это не помогает.

function compareKeypoints(varifiedKeypoints) {

  outer_loop: for (i = 0; i < varifiedKeypoints.length; i++) {

    let initialKeypoint = varifiedKeypoints[i];

    for (j = 0; j < varifiedKeypoints.length; j++) {

      let comparisonKeypoint = varifiedKeypoints[j];

      if (initialKeypoint.part != comparisonKeypoint.part) {

        if (Math.abs(comparisonKeypoint.position.x - initialKeypoint.position.x) <= 20
        && Math.abs(comparisonKeypoint.position.y - initialKeypoint.position.y) <= 20) {

          if (keypointsCompatible(initialKeypoint.part, comparisonKeypoint.part)) {

            console.log("Activating part: " + initialKeypoint.part);
            console.log("Activated part: " + comparisonKeypoint.part);

            let keypointPair = {
              point_1: initialKeypoint.part,
              point_2: comparisonKeypoint.part
            }

            console.log("Pushing parts!");
            activeParts.push(keypointPair);

            console.log("breaking loop!");
            break outer_loop;

            console.log("Loop NOT broken!!");

          }
        }
      }
    }
  }

  if (activeParts.length > 0) {
    console.log(activeParts);
  }
}

function keypointsCompatible(keypoint_1, keypoint_2) {

  var outcome = true;

  if (activeParts.length > 0) {

    compatibility_loop: for (i = 0; i < activeParts.length; i++) {

      if (Object.values(activeParts[i]).includes(keypoint_1) && Object.values(activeParts[i]).includes(keypoint_2)) {

        console.log(keypoint_1 + " and " + keypoint_2 + " are not compatible because they already exist as " + activeParts[i].point_1 + " and " + activeParts[i].point_2 + " respectively");

        outcome = false;

        break compatibility_loop;

        console.log("Compatibility NOT broken!!");
      }
    }
  }

  console.log("Compatibility outcome is " + outcome);
  return outcome;
}

Предполагается, что код принимает два значения в одном массиве и сравнивает их.Если выполняется ряд условий, в том числе если они находятся на определенном расстоянии друг от друга, они будут помещены во вторичный массив.Если значения уже появляются во вторичном массиве, который, как предполагается, должна определить функция keypointCompatible, цикл должен либо продолжить поиск других кандидатов, либо остановиться перед повторным вызовом.Однако по какой-то причине код застревает в функции keypointCompatible, когда он обнаруживает, что значения уже появились во вторичном массиве, и консоль будет многократно выводить «Совместимость ложна», пока не произойдет сбой браузера.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Ваш код должен быть в порядке, если varifiedKeypoints.length имеет разумное значение.И все внутренние переменные объявлены правильно!

У вас есть два цикла (этот внутренний может начинаться с j=i+1 для экономии времени и нескольких вычислений) с несколькими условиями внутри.

function compareKeypoints(varifiedKeypoints) {

  outer_loop: for (let i = 0; i < varifiedKeypoints.length; i++) {

    let initialKeypoint = varifiedKeypoints[i];

    for (let j = i+1; j < varifiedKeypoints.length; j++) {

      let comparisonKeypoint = varifiedKeypoints[j];
0 голосов
/ 22 января 2019

Рабочий раствор

Используйте let или const вместо var или ничего.Ваша проблема может быть связана с замыканиями и переменными, повторно используемыми между циклами.Убедитесь, что вы используете let или const в своих циклах.for (let i=0).

Когда вы используете let или const, среда выполнения будет создавать новый экземпляр каждый раз, когда блок или цикл повторяется.Однако использование var приведет к повторному использованию внутреннего распределения.

Итак, что происходит со стандартом var, так это то, что каждый из нескольких замыканий или циклов использует один и тот же экземпляр переменной.

Если только выхотите поведение var, всегда используйте let или const.


Другое решение

Поставьте новую строку после метки compatibility_loop

StillДругое решение

Первая функция выдвигается в activeParts.Вторая функция зацикливается activeParts.Это может продолжаться вечно или дольше, чем ожидалось.Вставка в массив может привести к тому, что предел цикла никогда не будет достигнут.Поместите журнал длины activeParts во вторую функцию, чтобы увидеть, выходит ли он из-под контроля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...