Проблема с Javascript параллельными массивами на основе запроса пользователя. Как перестать выходить за границы массива в l oop? - PullRequest
0 голосов
/ 26 апреля 2020

У меня проблемы с этой проблемой. Программа просит принять участие в создании программы, которая запрашивает входные данные о количестве студентов и о том, сколько тестов они прошли в этом семестре. Затем пользователь должен иметь возможность вводить данные в параллельный массив.

Пока что это то, что у меня есть.

function getScores() {
        let studentNames = [];
        let studentScores = [];
        var arr = [];
        let input = "";
        let nStudents = parseInt(prompt("How many students are there?"));
        for (i = 0; studentNames.length < nStudents; i++) {
          let name = prompt("Enter the students names");
          studentNames.push(name);
        }
        let nTest = parseInt(
          prompt(
            "How many test did the " +
              studentNames.length +
              " student each take?"
          )
        );
        let temp = nTest * studentNames.length;
        for (i = 0; i < temp; i++) {
          while (i < temp) {
            let score = parseInt(
              prompt(
                "What was " + studentNames[i] + "'s Test " + " " + i + " score?"
              )
            );
            studentScores.push(score);
            i++;
          }
        }
        console.log(studentNames);
        console.log(studentScores);
      }
      getScores();

Как видите, есть несколько проблем.

  1. Мой второй l oop будет перебирать имена, но как только достигает последней длины массива, просто переходит в новый индекс и получает значение undefined. Я попытался остановить l oop, когда он достигнет конца, но это излишне, так как мне нужно ввести все результаты теста.
  2. Другая проблема заключается в том, что я перебираю тест таким образом, который повторяется +1 после каждого нового студента. Я не хочу этого Я хотел бы, чтобы каждая итерация l oop говорила «Тест 1» для каждого учащегося, а затем снова переходила к «Тесту 2» для каждого учащегося.

Мне трудно понять, где я Я собираюсь об этом неправильно. Я знаю, что мои циклы просто не верны, и, скорее всего, есть гораздо более простое решение, такое как 2d массив, но я пытаюсь использовать параллели.

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

Кажется, что делать это с параллельным массивом было бы ОЧЕНЬ сложно, потому что мы не знаем количество тестов и учеников, пока не появится приглашение пользователя.

Если есть более простой способ на go об этом, мне интересно. Я не уверен, правильно ли я выполняю этот метод параллельного массива, и мне бы очень хотелось, чтобы некоторые из них поделились своими соображениями, поскольку я все еще плохо знаком с Javascript и массивами.

1 Ответ

0 голосов
/ 26 апреля 2020

Используйте объект, а не два массива. Я собираюсь предположить, что имена учеников уникальны (хотя в реальной жизни это не так, поэтому мы используем номера учеников), поэтому выделите один объект studentScores и используйте его в качестве карты:

const studentScores = {};

const N = parseInt(prompt("How many students are there?"));
for (let i=0; i < N; i++) {
  let name = prompt("Enter the students names");
  if (name) {
    studentScores[name] = 0;
  }
}

const T = get number of tests
Object.keys(studentScores).forEach(function(name) {
  for (let i=0; i<T; i++) {
    let score = parseFloat(prompt(`What did ${name} score on test ${i}?`));
    if (score) {
      studentScores[name] += score;
    }
  }
});

Если вам абсолютно необходимо использовать параллельные массивы, потому что вы пытаетесь понять, как их использовать, базовая концепция c состоит в том, чтобы никогда не вставлять или извлекать sh из одного массива или извлекать его. Ваши массивы связаны: если вы набираете sh или не переключаетесь, вы делаете это для обоих. Если вы щелкаете или сдвигаетесь, вы делаете это для обоих:

function getScores() {
  let input;

  const names = [],
    scores = [];

  // Get the number of students but VERIFY that you got a number:
  input = prompt("How many students are there?");
  const studentCount = parseInt(input);

  // There are many ways to verify this, but using JS coercion through ==
  // works quite well. This is one of the few times that == makes sense.
  if (studentCount == input) {
    for (let i = 0; i < studentCount; i++) {
      let name = prompt(`Please give the name for student number ${i}`);
      if (name) {
        // Here we GUARANTEE that the array positions for
        // this name and the associated score are the same:
        // if we push to `names`, we also push to `scores`,
        // so there is no possibility for the two getting
        // "out of sync" with respect to indexing
        names.push(name);
        scores.push(0);
      }
    }
  }

  input = prompt("How many tests did each student take?");
  const testCount = parseInt(input);

  if (testCount == input) {
    names.forEach(function(name, position) {
      for (let i = 0; i < testCount; i++) {
        input = prompt(`What did ${name} score for test ${i}?`);
        let score = parseFloat(input);
        if (score == input) {
          scores[position] += score;
        }
      }
    });
  }
}

Также обратите внимание, что я исправил некоторые вещи в вашем коде: не думайте, что prompt дает вам что-нибудь: это можно отменить, и ваш код сломается, если вы не будете проверять это. Кроме того, parseInt или parseFloat не дают вам число, они могут дать вам число, поэтому проверьте, что они действительно делают, прежде чем переходить к коду, который основан на числах.

Кроме того, строковая композиция: не используйте string + string, используйте литералы шаблона и шаблон в ваших значениях. Возьмите эту привычку сейчас, она предотвращает множество ошибок, связанных с композицией строк, и головную боль позже, в другом коде.

Затем обратите внимание, что мы используем for (let i=...): это сохраняет i в области видимости для l oop: он не будет существовать до его запуска и не будет существовать после того, как будет выполнен. В отличие от того, когда вы используете for(i=...), который совпадает с for(var i=...) и фактически делает i переменной области действия, то есть уже существует до запуска кода функции и продолжает существовать после вашего l oop сделано. Что почти никогда не то, что вы хотите.

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