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

时间:2019-10-25 17:13:12

标签: javascript arrays object

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

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
 },
]

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
 }
}

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

4 个答案:

答案 0 :(得分:1)

您想要的输出不是有效的数组,但是您可以使用对象代替

  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)

请记住,如果您想改为需要添加以下值,那么每年将只有1个值:

resultObject[key][year] = resultObject[key][year] + elm[key]

EDIT(基于OP更新)在这种情况下,也没有理由为javscript对象添加引号。如果以后需要成为JSON对象,只需使用以下命令将其转换:

JSON.parse(resultObject) which will make sure all keys have quotation marks

答案 1 :(得分:1)

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

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

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
 },
]

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.
    let thisYear = 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(propName !== 'years'){
        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));

正如所指出的,从功能的角度来看,删除“ years”属性是不好的形式。编辑代码以仅检查给定属性是否为“ years”。

答案 2 :(得分:1)

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

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)

答案 3 :(得分:1)

目标是最大程度地减少迭代同一组对象的次数。

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
 },
]

let output={};

array.forEach(obj=>{
  Object.keys(obj).filter(key=>key!=="years")
  .forEach(key=>{
    output[key] = output[key] || {};
    output[key][obj.years]=obj[key]
  })
})

console.log(output)