Есть упражнение, с которым я работал, которое запрашивало функцию для создания вложенного массива в объект.

Пример ввода: [['make', 'Ford'], ['model', 'Mustang'], ['year', 1964]] Ожидаемый результат: { make: 'Ford', model: 'Mustan', year: 1969 }

Я попытался это, написав это:

function fromListToObject(array) {
    let obj = {};

    for (var i = 0; i < array.length; i++) {
        obj[arr[i][0]] = arr[i][1];
    }
}

Но это не сработало, поэтому я нашел другое решение, и он использовал Reduce:

function fromListToObject(array) {
  return array.reduce(function(acc, curr) {
    acc[curr[0]] = curr[1];
    return acc;
}, {});
}

Теперь я подумал, что понимаю, как работает Reduce, но никогда не путался с объектами, как работает acc[curr[0]]? Он начинается как пустой объект, но я не понимаю, что такое acc после первой итерации. Кто-нибудь может объяснить, пожалуйста?

Заранее спасибо!

0
user7496931 25 Авг 2017 в 00:28

6 ответов

Лучший ответ

«Теперь я подумал, что понял, как работает Reduce, но никогда не связывался с ним для объектов, как acc[curr[0]] работает?»

acc всегда является возвращаемым значением из предыдущей итерации (или на первой итерации, начальным значением, если оно предоставляется, иначе первым элементом массива).

Так как вы всегда возвращаете acc, то есть {}, с которого вы начали, то acc всегда является этим начальным объектом.

И curr - это текущий элемент массива, который является подмассивом, содержащим ключ и значение, которое вы добавляете к объекту acc.

0
spanky 24 Авг 2017 в 21:32

уменьшение применяет функцию, которую вы передаете ему каждому элементу данного списка. Функция получает элемент и аккумулятор. В конце вы получите один результат.

Таким образом, простой случай - что-то вроде reduce([1,2,3], +, 0), просто суммирует значения, так как аккумулятор будет начинаться с 0, а затем суммировать каждый элемент с ним.

В вашем случае аккумулятор является объектом, поэтому, когда вы перебираете первый элемент, он будет выглядеть примерно так:

acc = {}
element = ['make', 'ford']

И поэтому вы меняете аккумулятор, используя element[0] в качестве ключа и element[1] в качестве значения, преобразовывая acc в { make: 'ford' }.

0
Mario F 24 Авг 2017 в 21:36

reduce принимает функцию и начальное значение. Функция вызывается для каждого элемента в массиве и возвращает результат для этого шага. При первом вызове передается начальное значение, передаваемое в Reduce (), а при каждом другом вызове передается результат предыдущего вызова функции.

Так что в вашем случае он расширяется следующим образом (где f - функция, которую вы передаете):

let default = {};
let a = f(['make', 'Ford'], default); // initial call uses default value
let b = f(['model', 'Mustang'], a); // uses result of previous call
let c = f(['year', '1964'], b);

Поскольку вы возвращаете ссылку на тот же объект, который вы передаете, по умолчанию a, b и c будут ссылками на один и тот же объект. Вы модифицируете объект на каждом шаге, так что все в порядке.

0
Jason Goemaat 24 Авг 2017 в 21:40

Ваша первая функция выглядит так, как будто бы она работала в том формате, в котором вы работали, я думаю, что она не сработала, потому что имя переменной arr не существует. это должен быть array параметр, который вы передаете в функцию.

function fromListToObject(array) {
  let obj = {};

  for (var i = 0; i < array.length; i++) {
    obj[array[i][0]] = array[i][1];
  }
}
0
Timmehlkk 24 Авг 2017 в 21:47

Reduce дает вашей функции обратного вызова объект. Затем вашей функции обратного вызова необходимо вернуть объект, который затем снова передается в ваш обратный вызов на следующей итерации. Так же, как и в случае с массивом, вы можете изменить свой объект так, как считаете нужным.

Короче говоря, в первой итерации приведения к переменной acc находится объект, который вы передаете второму аргументу функции приведения. Но для каждой итерации после этого значение acc является значением, возвращаемым вашим обратным вызовом в предыдущей итерации.

0
Joseph Ditton 24 Авг 2017 в 21:35

Вы можете использовать array в качестве имени переменной и вернуть obj.

function fromListToObject(array) {
    let obj = {};

    for (var i = 0; i < array.length; i++) {
        obj[array[i][0]] = array[i][1];
    }
    return obj;
}

console.log(fromListToObject([['make', 'Ford'], ['model', 'Mustang'], ['year', 1964]]))
0
Nina Scholz 24 Авг 2017 в 21:31