#javascript #angularjs
У меня есть пара массивов. Нужно занести определенные значения в нужные места. Здесь даже не столько AngularJS нужен, сколько чистый JS: проход по массивам и т.д. Мои массивы: $scope.usersNew - массив пользователей с ответами на вопрос анкеты. Структура такая: id - идентификатор, понятно. user - имя пользователя, questions - массив ответов на вопросы. Его структура следующая: id вопроса, name вопроса, answer - собственно, ответ. По умолчанию записана строка "No answer". $scope.anss - массив всех ответов из базы данных. Структура (та ее часть, которую я использую): sessionID - идентификатор сессии, аналог имени пользователя, questionAnswer - структура, в которой хранится информация о вопросе и ответе. Из нее беру: question - структура с информацией о вопросе. Я использую только поле id, answer - структура с информацией об ответе. Я использую поле text Мой код: // формирование массива пользователей с ответами // проход по пользователя for (var k = 0; k < $scope.usersNew.length; k++) { // проход по ответам for (var i = 0; i < $scope.anss.length; i++) { // принадлежность ответа пользователю if ($scope.anss[i].sessionID == $scope.usersNew[k].user) { // проход по ответам пользователя for (var j = 0; j < $scope.usersNew[k].questions.length; j++) { // соответствие ответов по id вопроса if ($scope.usersNew[k].questions[j].id == $scope.anss[i].questionAnswer.question.id) { // присвоение ответа пользователю $scope.usersNew[k].questions[j].answer = $scope.anss[i].questionAnswer.answer.text; break; break; } } } } } Дебаггер показал, что в строке присвоения ответа пользователю программа записывает этот ответ сразу всем пользователям, хотя пользователи вроде как перебираются в самом верхнем for. У меня появилась мысль: может, дело в том, как я заполняла первый массив usersNew? Когда записывала в поля answer значение "No answer", это выглядело примерно так: for (var i = 0; i < $scope.anss.length; i++) { var item = { id: "", user: "", questions: {} } item.id = $scope.anss[i].id; item.user = $scope.anss[i].sessionID; item.questions = $scope.arrForAns; users.push(item); } Где $scope.arrForAns - массив, созданный таким образом: $scope.arrForAns = answers.questions; // answers.questions - это массив объектов, который я достала из JSON, там уже есть id и name for (var i = 0; i < $scope.arrForAns.length; i++) { $scope.arrForAns[i].answer = "No answer"; } Я вроде читала, уже не уверена где, что с присвоением массивов есть загвоздка: что копируются не данные, а ссылки, и, возможно, в памяти лежит один несчастный массив questions на всех пользователей, и он-то и терзается со всех сторон. Или я ошибаюсь, и это я читала о чем-то другом.
Ответы
Ответ 1
Да. Для всего, кроме примитивных типов копируется ссылка. К примитивным типам относятся созданные без использования new числа, строки и bool'ы, а также null и undefined. PS: Не лень было такой вопрос задавать вместо того, чтобы погуглить про передачу по ссылке? гугл объяснил в чем дело, но его решение почему-то не помогает Не очень разобрался со всей структурой, но подозреваю, что это из-за того, что внутри массива тоже ссылки. Ангуляр позволяет сделать глубокую копию при помощи angular.copy: item.questions = angular.copy($scope.arrForAns);Ответ 2
Хронический пример "Closures". Самый простой способ решения - поместить содержание внутренних for(){} на тот же уровень, где находится сам цикл, например: function closure1() { function binder1(x){ return function(){ return x; }; } var arr = [], i; for (i = 0; i <10; i++){ arr[i] = binder1(i); } return arr; } console.log(closure1()); Или заменить присвоение ответа пользователю на: // соответствие ответов по id вопроса if ($scope.usersNew[k].questions[j].id == $scope.anss[i].questionAnswer.question.id) { // присвоение ответа пользователю (function(k, j, i) { return function() { $scope.usersNew[k].questions[j].answer = $scope.anss[i].questionAnswer.answer.text; }; })(k, j, i) } Проверять, если честно, лень, но смысл в том, что вам надо создать ещё один контекст для хранения j, i и k.
Комментариев нет:
Отправить комментарий