首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >迭代对象数组,对具有相同索引的值求和,然后返回新的对象数组

迭代对象数组,对具有相同索引的值求和,然后返回新的对象数组
EN

Stack Overflow用户
提问于 2018-06-10 22:02:52
回答 7查看 184关注 0票数 6

我有一个对象数组,如下所示:

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求和。yz也是如此。最终结果应该是一个新的对象数组,其中包含求和的值。

如下所示:

[
  [{totalXOne: 2}, {totalYOne: 4}, {totalZOne: 6}],
  [{totalXTwo: 2}, {totalYTwo: 4}, {totalZTwo: 6}],
  [{totalXThree: 2}, {totalYthree: 4}, {totalZThree: 6}],
]

注意:所有数组的长度都相同,如果缺少一个值,它将被替换为0)

我在MDN上发现了一些不错的东西,但它将所有xyz值求和,并返回单个求和值,如下所示:

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任何其他属性,它就在那里。有什么建议吗?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 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; }

票数 3
EN

Stack Overflow用户

发布于 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);

票数 2
EN

Stack Overflow用户

发布于 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);

希望这能有所帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50784499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档