Самый эффективный способ преобразования массивов объектов - PullRequest
1 голос
/ 25 октября 2019

Я хочу преобразовать этот массив объектов в другой массив объектов, но по-другому. Какой метод наиболее эффективен и / или быстрее (с точки зрения производительности, если массивов огромное количество)? Должен ли я использовать 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 ]

1 голос
/ 25 октября 2019

Цель - минимизировать количество повторений одного и того же набора объектов.

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)
1 голос
/ 25 октября 2019

Ваша возвращенная вещь, скорее всего, будет не массивом, а объектом. opex, netRevenue, payroll и т.п. приведут к получению ключей возвращаемого объекта.

При этом 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' является плохой формой с функциональной точки зрения. Отредактировал код, чтобы просто проверить, является ли данное свойство значением 'лет'.

1 голос
/ 25 октября 2019

Предполагая, что все объекты в вашем массиве имеют одинаковые свойства, вы можете собрать ключи первого объекта и использовать их для прочесывания всего массива:

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)
1 голос
/ 25 октября 2019

Ваш желаемый вывод не является допустимым массивом, но вы можете сделать это с помощью объекта вместо этого

  1. сначала вы переберите массив и
  2. получите значение года
  3. затем получите все ключи к объекту
  4. проверьте, чтобы убедиться, что ключ не 'лет', поскольку вы не хотите, чтобы это было в вашем результате согласно спецификации
  5. , чтобы проверить, является ли этот ключсуществует в resultObject
  6. , если нет, то создайте новый объект с ключом элементов
  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...