变换对象数组的最有效方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了变换对象数组的最有效方法相关的知识,希望对你有一定的参考价值。

我想将此对象数组转换为另一个对象数组,但以不同的方式输出。什么是最有效的方法和/或最快的方法(如果有大量数组,就性能而言)?我应该使用for ... on,lodash,filter还是reduce?谢谢

let array = [
 {
   "years": "2018", "opex": 90000, "netRevenue": 50000, "payroll": 60000, "rent":20000, "marketing":5000, "other":5000
 },
 {
   "years": "2018", "opex": 108500, "netRevenue": 55000, "payroll": 70000, "rent":22500, "marketing":10000, "other":6000
 },
 {
   "years": "2019", "opex": 153000, "netRevenue": 120000, "payroll": 100000, "rent":25000, "marketing":20000, "other":8000
 },
]

to

let array = {
 "opex":{
  "2017":90000, "2018":108500, "2019":153000
 },
 "netRevenue":{
  "2017":50000, "2018":55000, "2019":120000
 },
 "payroll":{
  "2017":60000, "2018":70000, "2019":100000
 },
 "rent":{
  "2017":20000, "2018":22500, "2019":25000
 },
 "marketing":{
  "2017":5000, "2018":10000, "2019":20000
 },
 "other":{
  "2017":5000, "2018":6000, "2019":8000
 }
}

更新在需要的地方添加双引号

答案

假设数组中的所有对象都具有相同的属性,您可以收集第一个对象的键并将其用于梳理整个数组:

let array = [ { years: 2017, opex: 90000, netRevenue: 50000, payroll: 60000, rent:20000, marketing:5000, other:5000 }, { years: 2018, opex: 108500, netRevenue: 55000, payroll: 70000, rent:22500, marketing:10000, other:6000 }, { years: 2019, opex: 153000, netRevenue: 120000, payroll: 100000, rent:25000, marketing:20000, other:8000 } ];

var keys=Object.keys(array[0]).slice(1);
var res={};
keys.forEach(k=>res[k]={});
array.forEach(c=>
  keys.forEach(k=>res[k][c.years]=c[k]));
console.log(res)
另一答案

您返回的内容可能不是数组,而是对象。 opexnetRevenuepayroll等将结束返回对象的键。

就是说,在此Array.reduce()中,这是一个非常有用的工具。

let array = [
 {
   years: 2018, opex: 90000, netRevenue: 50000, payroll: 60000, rent:20000, marketing:5000, other:5000
 },
 {
   years: 2018, opex: 108500, netRevenue: 55000, payroll: 70000, rent:22500, marketing:10000, other:6000
 },
 {
   years: 2019, opex: 153000, netRevenue: 120000, payroll: 100000, rent:25000, marketing:20000, other:8000
 },
]

function turnArrayToDataPoints(arr){
  /****
   * This reduce will return an object, and each of the departments will be an
   *   array with elements that look like `2017:25000`.
   ****/
  const remappedArray = arr.reduce((returnObj, element)=>{
    // the years property is unique, so we'll pull it out and then remove it.
    let thisYear = element.years;
    delete element.years;
    
    // Now, we can iterate over the properties for the current element in arr.
    //  if we have NOT created a property with this name on our return object,
    //  we want to create an empty array. Then, either way, we push a string on.
    for(let propName in element){
      if(!returnObj.hasOwnProperty(propName))
        returnObj[propName] = {};
      returnObj[propName][thisYear] = element[propName];
    }
    // And within our reduce, we need to remember to return our object.
    return returnObj;
  }, {}) //<-- this is the empty object we'll populate above.
  
  return remappedArray;
}

console.log(turnArrayToDataPoints(array));
另一答案

您想要的输出不是有效的数组,但是您可以使用一个对象来完成此操作

  1. 首先,您将遍历数组和
  2. 获取年份值
  3. 然后获取对象的所有键
  4. 检查以确保密钥不是'years',因为您不希望按规范显示结果中的密钥
  5. 检查该键是否存在于resultObject中
  6. 如果没有,则使用elements键创建一个新对象
  7. 如果有,则将元素添加到对象键处

let array = [{years: 2018, opex: 90000, netRevenue: 50000, payroll: 60000, rent:20000, marketing:5000, other:5000},{years: 2018, opex: 108500, netRevenue: 55000, payroll: 70000, rent:22500, marketing:10000, other:6000},{years: 2019, opex: 153000, netRevenue: 120000, payroll: 100000, rent:25000, marketing:20000, other:8000},]

const resultObject = {}

array.forEach(elm=>{
  const year = elm.years

  Object.keys(elm).forEach(key=>{
     if(key === 'years') return

     if(!resultObject[key]){
      resultObject[key] = {[year]:elm[key]}
     } else {
      resultObject[key][year] = elm[key]
     }
  })
})

console.log(resultObject)

以上是关于变换对象数组的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

在Javascript中更新对象数组中的键的最有效方法是啥? [复制]

识别和删除数组中重复项的最有效方法是啥?

在任意数量的数组之间找到共同项的最有效方法

在 Java 中查看 ArrayList 是不是包含对象的最有效方法

在 React 中迭代数据数组时呈现 JSX 元素的最有效方法

检查数组是不是包含Java中的值的最有效方法? [复制]