使用 JavaScript 合并具有特定键值的数组

4

我有一个像这样的数组:

var arr = [{
  "date": "JAN",
  "value": 5,
  "weight": 3
}, {
  "date": "JAN",
  "value": 4,
  "weight": 23
}, {
  "date": "FEB",
  "value": 9,
  "weight": 1
}, {
  "date": "FEB",
  "value": 10,
  "weight": 30
}]

我想匹配这里的主键日期。匹配后,我想合并其余的键值,并获得以下输出:

[{
  "date": "JAN",
  "value": [5, 4],
  "weight": [3, 23]
}, {
  "date": "FEB",
  "value": [9, 10],
  "weight": [1, 30]
}]

我写了一个类似这样的函数,但是不知道如何连接键值:

var arr = [{
  "date": "JAN",
  "value": 5,
  "weight": 3
}, {
  "date": "JAN",
  "value": 4,
  "weight": 23
}, {
  "date": "FEB",
  "value": 9,
  "weight": 1
}, {
  "date": "FEB",
  "value": 10,
  "weight": 30
}]

const transform = (arr, primaryKey) => {
  var newValue = [];
  for (let i = 0; i < arr.length; i++) {
    for (let j = 1; j < arr.length; j++) {
      if (primaryKey[i] === primaryKey[j]) {
        newValue.push({
          ...arr[i],
          ...arr[j]
        });
      }
    }
  }
  return newValue
};

console.log(transform(arr,'date'))

3个回答

2
以下代码应该可以正常工作:
const transform = (arr, primaryKey) => {
    var newValue = [];
    for(let i = 0; i < arr.length; i++){
        arr[i]["value"] = [arr[i]["value"]];
        arr[i]["weight"] = [arr[i]["weight"]];
    }
    newValue.push(arr[0])
    for(let i = 1; i < arr.length; i++){
        let contains = false;
        for(let j = 0; j < newValue.length; j++){
            if(newValue[j][primaryKey] == arr[i][primaryKey]){
                newValue[j]["value"].push(arr[i]["value"][0]);
                newValue[j]["weight"].push(arr[i]["weight"][0]);
                contains = true;
            }
        }
        if(!contains){
            newValue.push(arr[i]);
        }
        
    }
   return newValue
};

var arr = [{
              "date": "JAN",
              "value": 5,
              "weight": 3
          }, {
              "date": "JAN",
              "value": 4,
              "weight": 23
          }, {
              "date": "FEB",
              "value": 9,
              "weight": 1
          }, {
              "date": "FEB",
              "value": 10,
              "weight": 30
          }] 
          
var newthing = transform(arr,"date");
console.log(newthing);

输出:

[ { date: 'JAN', value: [ 5, 4 ], weight: [ 3, 23 ] },
  { date: 'FEB', value: [ 9, 10 ], weight: [ 1, 30 ] } ]

这段代码的工作方式是,首先将 "value""weight" 键的值转换为列表。
然后,我们从将 arr 的第一个元素推入 newValue 开始。
从这里开始,我们使用嵌套的 for 循环来迭代剩下的 arrnewValue
如果每个 arr 元素的 "date" 值已经存在于 newValue 中,则将属于 arr"value""weight" 的值推入其中。
但是,如果不存在,则只需将该元素推入 newValue 中。
希望这能回答您的问题!如果您需要任何进一步的帮助或澄清,请告诉我 :)

2
  • 使用 Array#reduce,遍历列表并更新一个 Map,其中 key 是主键,值是分组对象。在每次迭代中,创建/更新这对键值对。
  • 使用 Map#values,返回分组对象的列表。

const transform = (arr, primaryKey) => [...
  arr.reduce((map, { [primaryKey]: key, ...e }) => {
    const { [primaryKey]: k, ...props } = map.get(key) ?? {};
    for(let prop in e) {
      props[prop] = [...(props[prop] ?? []), e[prop]];
    }
    map.set(key, { [primaryKey]: key, ...props });
    return map;
  }, new Map)
  .values()
];

const arr = [ { "date": "JAN", "value": 5, "weight": 3 }, { "date": "JAN", "value": 4, "weight": 23 }, { "date": "FEB", "value": 9, "weight": 1 }, { "date": "FEB", "value": 10, "weight": 30 } ]; 
console.log( transform(arr, 'date') );


0

结合几个reduce也可以完成同样的工作:

const arr = [{
              "date": "JAN",
              "value": 5,
              "weight": 3
          }, {
              "date": "JAN",
              "value": 4,
              "weight": 23
          }, {
              "date": "FEB",
              "value": 9,
              "weight": 1
          }, {
              "date": "FEB",
              "value": 10,
              "weight": 30
          }] 

const arrayMappedByDate = arr.reduce((acc, curData) => {
  if (acc[curData.date]) {
    acc[curData.date].push(curData)
  } else {
    acc[curData.date] = [curData]
  }
  return acc
}, {})

const transformedArray = Object.entries(arrayMappedByDate).map(([dateInit, data]) => {
 const normalized = data.reduce((acc, cur) => {
   if (acc.date) {
     acc.value.push(cur.value)
     acc.weight.push(cur.weight)
   } else {
     acc = { 
       date: cur.date,
       value: [cur.value],
       weight: [cur.weight]
     }
   }
   return acc
 }, {})
 return { [dateInit]: normalized }
})


 console.log(transformedArray)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接