简体   繁体   English

在Javascript中合并具有相同键和不同长度的两个数组

[英]Merge two arrays with the same keys and different length in Javascript

I am trying to solve the problem but couldn't figure out how to do it. 我正在尝试解决问题,但不知道如何解决。 I have two arrays: 我有两个数组:

var arr1 = [
     {Week: "WK1", CreatedTickets: 1}, {Week: "WK3", CreatedTickets: 12}, 
     {Week: "WK2", CreatedTickets: 3}, {Week: "WK5", CreatedTickets: 5}
];

var arr2 = [
     {Week: "WK1", ClosedTickets: 4}, {Week: "WK6", ClosedTickets: 40},
     {Week: "WK3", ClosedTickets: 33}, {Week: "WK2", ClosedTickets: 2}
 ];

The expected output would be and the week should be in order as well. 预期的产量应该是,并且星期也应该井井有条。

var output = [
     {Week: "WK1", CreatedTickets: 1, ClosedTickets: 4}, 
     {Week: "WK2", CreatedTickets: 3, ClosedTickets: 2},
     {Week: "WK3", CreatedTickets: 12, ClosedTickets: 33},
     {Week: "WK5", CreatedTickets: 5, ClosedTickets: 0},
     {Week: "WK6", CreatedTickets: 0, ClosedTickets: 33}
];

Please help me to solve this problem. 请帮我解决这个问题。 Thanks a lot. 非常感谢。

Jamie 杰米

To achieve expected result, use below option, 为了达到预期效果,请使用以下选项,

Two loops for getting exact output 两个循环以获得精确的输出

  1. First loop to create Object in below format 第一个循环以以下格式创建对象

    { {
    "WK1": { "CreatedTickets": 1, "ClosedTickets": 4 }, “ WK1”:{“ CreatedTickets”:1,“ ClosedTickets”:4},
    "WK2": { "CreatedTickets": 3, "ClosedTickets": 2 }, “ WK2”:{“ CreatedTickets”:3,“ ClosedTickets”:2},
    "WK3": { "CreatedTickets": 12, "ClosedTickets": 33 }, “ WK3”:{“ CreatedTickets”:12,“ ClosedTickets”:33},
    "WK5": { "CreatedTickets": 5, "ClosedTickets": 0 }, “ WK5”:{“ CreatedTickets”:5,“ ClosedTickets”:0},
    "WK6": { "CreatedTickets": 0, "ClosedTickets": 33 } “ WK6”:{“ CreatedTickets”:0,“ ClosedTickets”:33}
    } }

  2. Second loop for converting temp Object mentioned above to output array 将上面提到的临时对象转换为输出数组的第二个循环

    [ [
    {Week: "WK1", CreatedTickets: 1, ClosedTickets: 4}, {周:“ WK1”,CreatedTickets:1,ClosedTickets:4},
    {Week: "WK2", CreatedTickets: 3, ClosedTickets: 2}, {周:“ WK2”,CreatedTickets:3,ClosedTickets:2},
    {Week: "WK3", CreatedTickets: 12, ClosedTickets: 33}, {周:“ WK3”,CreatedTickets:12,ClosedTickets:33},
    {Week: "WK5", CreatedTickets: 5, ClosedTickets: 0}, {周:“ WK5”,CreatedTickets:5,ClosedTickets:0},
    {Week: "WK6", CreatedTickets: 0, ClosedTickets: 33} {星期:“ WK6”,CreatedTickets:0,ClosedTickets:33}
    ]; ];

JS JS

 var output =[];//output array var temp = {};//temp object var arr1 = [ {Week: "WK1", CreatedTickets: 1}, {Week: "WK3", CreatedTickets: 12}, {Week: "WK2", CreatedTickets: 3}, {Week: "WK5", CreatedTickets: 5} ]; var arr2 = [ {Week: "WK1", ClosedTickets: 4}, {Week: "WK6", ClosedTickets: 40}, {Week: "WK3", ClosedTickets: 33}, {Week: "WK2", ClosedTickets: 2} ]; var concatArr = arr1.concat(arr2) for(var o of concatArr){ if(Object.keys(temp).indexOf(o.Week)==-1){ temp[o.Week] ={} o.ClosedTickets?temp[o.Week].ClosedTickets = o.ClosedTickets:temp[o.Week].ClosedTickets = 0 o.CreatedTickets?temp[o.Week].CreatedTickets = o.CreatedTickets:temp[o.Week].CreatedTickets = 0 }else{ o.ClosedTickets?temp[o.Week].ClosedTickets = temp[o.Week].ClosedTickets + o.ClosedTickets:temp[o.Week].ClosedTickets o.CreatedTickets?temp[o.Week].CreatedTickets = temp[o.Week].CreatedTickets + o.CreatedTickets:temp[o.Week].CreatedTickets } } for( var key of Object.keys(temp)){ output.push({ Week:key, CreatedTickets:temp[key].CreatedTickets, ClosedTickets:temp[key].ClosedTickets }) } console.log(output) 

Code sample - https://codepen.io/nagasai/pen/RMNVvQ?editors=1010 代码示例-https: //codepen.io/nagasai/pen/RMNVvQ?editors=1010

You can map (using reduce ) the initial arrays to get a faster access to their keys, then execute a loop using forEach to build the desired result. 您可以映射(使用reduce )初始数组以更快地访问它们的键,然后使用forEach执行循环以构建所需的结果。

Now, execute a sort over result array using the Week value (Just the numbers). 现在,使用Week值(仅数字)对结果数组执行sort

 var arr1 = [{Week: "WK1", CreatedTickets: 1}, {Week: "WK20", CreatedTickets: 7}, {Week: "WK3", CreatedTickets: 12}, {Week: "WK2", CreatedTickets: 3}, {Week: "WK5", CreatedTickets: 5}], arr2 = [{Week: "WK1", ClosedTickets: 4}, {Week: "WK6", ClosedTickets: 40},{Week: "WK3", ClosedTickets: 33}, {Week: "WK2", ClosedTickets: 2}], // Convert to something like this: // { // "WK1": { // "Week": "WK1", // "CreatedTickets": 1 // }, // "WK20": { // "Week": "WK20", // "CreatedTickets": 7 // }, // } // // This is to speed up the access and comparisons. // map1 = arr1.reduce((a, o) => ({...a, ...{[o.Week]: o}}), {}), map2 = arr2.reduce((a, o) => ({...a, ...{[o.Week]: o}}), {}); // Now let's loop the keys of the previously mapped 'map1'. Object.keys(map1).forEach(k => { if (map2[k]) { // This is to avoid the values ("WK1", "WK2", and so on.) // because map1 already has that value. delete map2[k].Week; // Will generate something like this: // { // WK1: { // "Week": "WK1", // "CreatedTickets": 1, // "ClosedTickets": 4 // } // } map1[k] = { ...map1[k], ...map2[k] }; } else { // Will generate something like this: // { // WK1: { // "Week": "WK1", // "CreatedTickets": 7, // "ClosedTickets": 0 // To initialize qith zero because is an object that doesn't exists in map2 // } // } map1[k] = { ...map1[k], ...{CreatedTickets: map1[k].CreatedTickets, ClosedTickets: 0} }; } }); // Now the same forEach for the map2 to complete with the missing objects (weeks) in map1 Object.keys(map2).forEach(k => { if (!map1[k]) { map1[k] = { ...map1[k], ...{Week: map2[k].Week, CreatedTickets: 0, ClosedTickets: map2[k].ClosedTickets} }; } }); // Justa a sort var sorted = Object.values(map1).sort((a,b) => a.Week.replace(/[az]/gi, '') - b.Week.replace(/[az]/gi, '')); console.log(sorted); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

There are some shortcuts you could use if using ESNext features, but since you have been using var and not let / const , I'm assuming ES5 only. 如果使用ESNext功能,可以使用一些快捷方式,但是由于您一直在使用var而不是let / const ,所以我仅假设使用ES5。

So below is a simple solution. 所以下面是一个简单的解决方案。

 var arr1 = [ {Week: "WK1", CreatedTickets: 1}, {Week: "WK3", CreatedTickets: 12}, {Week: "WK2", CreatedTickets: 3}, {Week: "WK20", CreatedTickets: 7}, {Week: "WK5", CreatedTickets: 5} ]; var arr2 = [ {Week: "WK1", ClosedTickets: 4}, {Week: "WK6", ClosedTickets: 40}, {Week: "WK3", ClosedTickets: 33}, {Week: "WK2", ClosedTickets: 2} ]; //first lets make a copy of arr1 var output = arr1.slice(); //now loop arr2, and see if exists in ouput or not arr2.forEach(function (item) { //lets find in arr1 var f = output.find(function(i) { return item.Week === i.Week; }); if (f) { //ok found lets update f.ClosedTickets = item.ClosedTickets; } else { //not found lets add output.push(item); } }); //ok if we want 0, for OpenTickets and ClosedTickets if none found output.forEach(function (item) { item.ClosedTickets = item.ClosedTickets | 0; item.CreatedTickets = item.CreatedTickets | 0; }); //finally lets's sort //one gotcha, sorting by WK1,WK2,WK10 etc in string sort would give //WK1, WK10, WK2.. so we will use regex to extract just the wk part //convert to integer and then sort var regexnum = /\\d+/; function numWk(s) { return parseInt(regexnum.exec(s.Week)[0], 10); } output.sort(function (a,b) { return numWk(a) - numWk(b); }); console.log(output); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM