使用 reduce 将嵌套数组转换为对象
Turning a nested array into an object with reduce
我正在做一个练习,要求一个函数将嵌套数组创建到一个对象中。
示例输入:[['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
是什么感到困惑。谁能解释一下?
提前致谢!
您可以使用 array
作为变量名,return 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]]))
"Now I thought I understood how reduce worked but never really messed with it for objects, how does acc[curr[0]]
work?"
acc
始终是前一次迭代的 return 值(或者在第一次迭代中,如果提供了起始值,否则是第一个数组元素)。
所以因为你总是 returning acc
,这是你开始的 {}
,所以 acc
总是那个起始对象。
而 curr
是数组中的当前项,它是包含要添加到 acc
对象的键和值的子数组。
Reduce 为您的回调函数提供一个对象。然后你的回调函数需要 return 一个对象,然后在下一次迭代中再次传递到你的回调中。因此,就像使用数组一样,您可以根据需要修改对象。
所以简而言之,在 reduce 的第一次迭代中,acc
变量是您传递给 reduce 函数的第二个参数的对象。但是对于此后的每次迭代,acc
的值是您在上一次迭代中回调的值 return。
reduce 将您传递给它的函数应用于给定列表的每个元素。该函数接收元素和累加器。最后你会得到一个结果。
所以一个简单的例子就像 reduce([1,2,3], +, 0)
,只是将值相加,因为累加器将从 0 开始,然后将每个元素相加。
在你的例子中,累加器是一个对象,所以当你遍历第一个元素时,它会是这样的:
acc = {}
element = ['make', 'ford']
因此您通过使用 element[0]
作为键并使用 element[1]
作为值来更改累加器,将 acc
转换为 { make: 'ford' }
。
reduce
接受一个函数和一个初始值。为数组中的每个元素调用该函数,returns 该步骤的结果。第一次调用传递给 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 都将是对同一对象的引用。您在每一步都修改对象,这样就没问题了。
您的第一个函数看起来可以按照您使用的格式运行,我认为它不起作用,因为变量名 arr
不存在。它应该是 array
您传递给函数的参数。
function fromListToObject(array) {
let obj = {};
for (var i = 0; i < array.length; i++) {
obj[array[i][0]] = array[i][1];
}
}
我正在做一个练习,要求一个函数将嵌套数组创建到一个对象中。
示例输入:[['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
是什么感到困惑。谁能解释一下?
提前致谢!
您可以使用 array
作为变量名,return 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]]))
"Now I thought I understood how reduce worked but never really messed with it for objects, how does
acc[curr[0]]
work?"
acc
始终是前一次迭代的 return 值(或者在第一次迭代中,如果提供了起始值,否则是第一个数组元素)。
所以因为你总是 returning acc
,这是你开始的 {}
,所以 acc
总是那个起始对象。
而 curr
是数组中的当前项,它是包含要添加到 acc
对象的键和值的子数组。
Reduce 为您的回调函数提供一个对象。然后你的回调函数需要 return 一个对象,然后在下一次迭代中再次传递到你的回调中。因此,就像使用数组一样,您可以根据需要修改对象。
所以简而言之,在 reduce 的第一次迭代中,acc
变量是您传递给 reduce 函数的第二个参数的对象。但是对于此后的每次迭代,acc
的值是您在上一次迭代中回调的值 return。
reduce 将您传递给它的函数应用于给定列表的每个元素。该函数接收元素和累加器。最后你会得到一个结果。
所以一个简单的例子就像 reduce([1,2,3], +, 0)
,只是将值相加,因为累加器将从 0 开始,然后将每个元素相加。
在你的例子中,累加器是一个对象,所以当你遍历第一个元素时,它会是这样的:
acc = {}
element = ['make', 'ford']
因此您通过使用 element[0]
作为键并使用 element[1]
作为值来更改累加器,将 acc
转换为 { make: 'ford' }
。
reduce
接受一个函数和一个初始值。为数组中的每个元素调用该函数,returns 该步骤的结果。第一次调用传递给 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 都将是对同一对象的引用。您在每一步都修改对象,这样就没问题了。
您的第一个函数看起来可以按照您使用的格式运行,我认为它不起作用,因为变量名 arr
不存在。它应该是 array
您传递给函数的参数。
function fromListToObject(array) {
let obj = {};
for (var i = 0; i < array.length; i++) {
obj[array[i][0]] = array[i][1];
}
}