我有一个对象数组,如下所示:
const data = [ // array1
[{x: 1}, {y:2}, {z:3}],
[{x: 1}, {y:2}, {z:3}],
[{x: 1}, {y:2}, {z:3}]
],[ // array2
[{x: 1}, {y:2}, {z:3}],
[{x: 1}, {y:2}, {z:3}],
[{x: 1}, {y:2}, {z:3}]
]
需要完成的是将array1
中的x
与具有相同索引的array2
中的x
求和。y
和z
也是如此。最终结果应该是一个新的对象数组,其中包含求和的值。
如下所示:
[
[{totalXOne: 2}, {totalYOne: 4}, {totalZOne: 6}],
[{totalXTwo: 2}, {totalYTwo: 4}, {totalZTwo: 6}],
[{totalXThree: 2}, {totalYthree: 4}, {totalZThree: 6}],
]
注意:所有数组的长度都相同,如果缺少一个值,它将被替换为0
)
我在MDN上发现了一些不错的东西,但它将所有x
、y
、z
值求和,并返回单个求和值,如下所示:
let initialValue = 0;
let sum = [{x: 1}, {x:2}, {x:3}].reduce(function(accumulator,currentValue) {
return accumulator + currentValue.x;
}, initialValue)
输出:
[
[{totalX: 3}, {totalY: 6}, {totalZ: 9}], // this is not what I need
]
我有什么方法可以做到这一点吗?
更新
我从另一个来源收到了JSON
。它包含一个名为allEmpsData
的属性,在它上面映射,我得到必要的salaryData
,然后在它上面映射,我得到净|毛|税数据。
let allReports = [];
setTimeout(() => {
allEmpsData.map(x => {
let reports = {};
let years = [];
let months = [];
let netArr = [];
let grossArr = [];
let mealArr = [];
let taxArr = [];
let handSalaryArr = [];
x.salaryData.map(y => {
years.push(y.year);
months.push(y.month);
netArr.push(y.totalNetSalary);
grossArr.push(y.bankGrossSalary);
mealArr.push(y.bankHotMeal);
taxArr.push(y.bankContributes);
handSalaryArr.push(y.handSalary);
})
reports.year = years;
reports.month = months;
reports.net = netArr;
reports.gross = grossArr;
reports.meal = mealArr;
reports.taxesData = taxArr;
reports.handSalaryData = handSalaryArr;
allReports.push(Object.assign([], reports));
});
}, 1000);
据我所知,一切都在正常运行,但事实是。我不知道还有什么更好的。然后魔术就来了:
setTimeout(() => {
result = allReports.reduce((r, a) =>
a.map((b, i) =>
b.map((o, j) =>
Object.assign(...Object
.entries(o)
.map(([k, v]) => ({ [k]: v + (getV(r, [i, j, k]) || 0) }))
)
)
),
undefined
);
console.log(result);
}, 1500);
..。它在节点控制台中返回一个空数组,但是如果我从上面更新的代码中console.log
任何其他属性,它就在那里。有什么建议吗?
发布于 2018-06-10 23:15:48
您可以使用helper函数来获取嵌套对象的值,并将这些值映射到相同的索引处。
const getV = (o, p) => p.reduce((t, k) => (t || {})[k], o);
var data = [[[{ x: 1 }, { y: 2 }, { z: 3 }], [{ x: 1 }, { y: 2 }, { z: 3 }], [{ x: 1 }, { y: 2 }, { z: 3 }]], [[{ x: 1 }, { y: 2 }, { z: 3 }], [{ x: 1 }, { y: 2 }, { z: 3 }], [{ x: 1 }, { y: 2 }, { z: 3 }]]],
result = data.reduce((r, a) =>
a.map((b, i) =>
b.map((o, j) =>
Object.assign(...Object
.entries(o)
.map(([k, v]) => ({ [k]: v + (getV(r, [i, j, k]) || 0) }))
)
)
),
undefined
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
发布于 2018-06-10 22:33:11
尝试以下操作:
var arr1 = [[{x: 1}, {y:2}, {z:3}], [{x: 1}, {y:2}, {z:3}], [{x: 1}, {y:2}, {z:3}]];
var arr2 = [[{x: 1}, {y:2}, {z:3}], [{x: 1}, {y:2}, {z:3}], [{x: 1}, {y:2}, {z:3}]];
var map = {
0 : 'x',
1 : 'y',
2 : 'z'
};
var map2 = {
0 :"One",
1 :"Two",
2 : "Three"
};
var result = [];
var obj= {};
for(var i = 0; i < arr1.length; i++){
total = 0;
var arr =[];
for(var j =0; j < arr1[i].length; j++){
obj["total"+ map[j] + map2[i]] = arr1[i][j][map[j]] + arr2[i][j][map[j]];
arr.push(obj);
obj = {};
}
result.push(arr);
}
console.log(result);
发布于 2018-06-10 22:24:25
试着把这类问题分解成更小的问题,然后逐渐积累起来,这是一个好主意。这意味着我们不必一次看完整个事情。
让我们编写一个函数,将数组中的各个元素相加:
function addElements(element1, element2, key, rowIndex) {
//for now we keep the keys the same, otherwise multiple additions
//won't work
return {
[key]: element1[key] + element2[key]
};
}
现在,让我们使用addElements()
将两行添加到一起
function addRows(row1, row2, rowIndex) {
return ['x', 'y', 'z'].map((key, index) => {
// "key" will go through "x", "y", and "z" as
// "index" goes 0, 1, 2
const element1 = row1[index];
const element2 = row2[index];
return addElements(element1, element2, key, rowIndex);
});
}
现在,我们可以遍历第一个矩阵中的所有行,并使用addRows()
添加第二个矩阵中的等价项
function addMatrices(matrix1, matrix2) {
return matrix1.map((row1, index) => {
const row2 = matrix2[index];
return addRows(row1, row2, index);
});
}
现在我们可以把它变成一个减速器:
const EMPTY_MATRIX = { ... }; //define a matrix of all zeroes here
matrices.reduce(addMatrices, EMPTY_MATRIX);
希望这能有所帮助!
https://stackoverflow.com/questions/50784499
复制相似问题