JS - я не понимаю, почему это объявление объекта не работает - PullRequest
0 голосов
/ 07 февраля 2020

Я только начинаю изучать JS, и у меня очень простой, но запутанный вопрос. Я попытался отладить свой код, чтобы увидеть, как это работает и почему он работает так, как работает, но я просто не понимаю. Ниже у меня есть моя функция вместе с примером ввода employeeData.

function transformEmployeeData(employeeData) {
  var result = [];
  var obj = {};
  for (var i = 0; i < employeeData.length; i++) {
    for (var j = 0; j < employeeData[i].length; j++) {
      obj[employeeData[i][j][0]] = employeeData[i][j][1];
    }
    result.push(obj);
  }
  return result;
}

var input = [
    [
        ['firstName', 'Joe'], ['lastName', 'Blow'], ['age', 42], ['role', 'clerk']
    ],
    [
        ['firstName', 'Mary'], ['lastName', 'Jenkins'], ['age', 36], ['role', 'manager']
    ]
]

/* Expected Results -
[
    {firstName: 'Joe', lastName: 'Blow', age: 42, role: 'clerk'},
    {firstName: 'Mary', lastName: 'Jenkins', age: 36, role: 'manager'}
] 

Actual Results - 
[
    {firstName: 'Mary', lastName: 'Jenkins', age: 36, role: 'manager'},
    {firstName: 'Mary', lastName: 'Jenkins', age: 36, role: 'manager'}
]*/

Я знаю, как исправить мой код, чтобы получить желаемые результаты, перемещая строку var obj = {}; сразу после for l oop из i. Чего я не понимаю, так это почему вышеприведенный код не работает? После завершения i = 0 объект obj сохраняет первый ожидаемый ввод и помещает его в массив результатов. Но затем он выдвигает массив Мэри и перезаписывает остальное, и я получаю фактический результат. Пара вопросов. Почему мой исходный объект, который правильно хранит данные Joe, исчезает из моего массива, и почему объект, содержащий данные Mary, вставляется дважды? Если я правильно понимаю мой код; for l oop для i должен повторяться только дважды, что означает, что в него должны быть вставлены только два объекта, но почему я получаю 2 Mary объекта внутри? И, наконец, почему объявление новой переменной объекта должно быть внутри начального for l oop?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Ваш код содержит только одну ошибку, в противном случае все в порядке,

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

Итак, вам нужно объявить var obj; вне l oop и поместить obj = {}; внутри первого для l oop, так что новый объект создается каждый раз, когда l oop повторяется ,

См. мой рабочий пример ниже:

function transformEmployeeData(employeeData) {
  var result = [];
  var obj;

  for (var i = 0; i < employeeData.length; i++) {
    obj = {};

    for (var j = 0; j < employeeData[i].length; j++) {
      obj[employeeData[i][j][0]] = employeeData[i][j][1];
    }
    result.push(obj);
  }
  return result;
}

var input = [
    [
        ['firstName', 'Joe'], ['lastName', 'Blow'], ['age', 42], ['role', 'clerk']
    ],
    [
        ['firstName', 'Mary'], ['lastName', 'Jenkins'], ['age', 36], ['role', 'manager']
    ]
]
console.log(transformEmployeeData(input));
0 голосов
/ 07 февраля 2020

Поскольку вы учитесь, вот мои 2 c для вашего учебного пути. Вместо бесконечных вложенных циклов, попробуйте использовать жемчужины функционального программирования, а именно: Array.prototype.map и Array.prototype.reduce . Используя их, вы можете добиться того, что вы делали, гораздо более элегантно (а зачастую и быстрее):

var input = [
    [
        ['firstName', 'Joe'], ['lastName', 'Blow'], ['age', 42], ['role', 'clerk']
    ],
    [
        ['firstName', 'Mary'], ['lastName', 'Jenkins'], ['age', 36], ['role', 'manager']
    ]
]

var transformedInput = input.map(function(el) {
    return el.reduce(function(result, elel) {
        result[elel[0]] = elel[1];
        return result;
    }, {});
})
...