查找对象数组中每个索引的平均值?

时间:2018-10-31 19:09:01

标签: javascript node.js lodash

我的大脑因此而融化...我正在努力实现以下目标:

我有一个对象数组,其中也有数组:

const data = [
  {
    seatChartResults: {
     '10th': [40, 40, 40, 39, 39, 38, 38, 38, 38, 38],
     '90th': [44, 44, 44, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
  {
    seatChartResults: {
     '10th': [41, 40, 40, 39, 39, 39, 38, 38, 38, 38],
     '90th': [43, 44, 45, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
]

现在,我想实现一些可以获取这些键的每个索引平均值的东西,例如:

(data[0].seatChartResults['10th'][0] + data[1].seatChartResults['10th'][0]) / 2

以此类推...

最终结果是将对象聚合为同一结构:

  { // With all averages aggregated
    seatChartResults: {
     '10th': [41, 40, 40, 39, 39, 39, 38, 38, 38, 38],
     '90th': [43, 44, 45, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },

这就是我现在拥有的:

const avgSeatChartResults = (allLambdas) => {

  return allLambdas.reduce((acc, { seatChartResults }) => {

    Object.keys(seatChartResults).forEach(key => {

      const allKeys = [acc.seatChartResults[key] = seatChartResults[key]]

      allKeys.map(item => item.reduce((acc, currValue) => acc + currValue, 0) / item.length )      

    })

    return acc

  }, { seatChartResults: {} })

}

但是...我不确定这样做是否正确。请帮忙。

3 个答案:

答案 0 :(得分:1)

您可以使用的一种方法是:

  • 首先计算对应数组的总和,然后将其收集在地图(或对象,如果您愿意的话)中
  • 然后通过计算每个数组中每个条目的平均值,将其进一步简化为所需的对象

const data = [{
    seatChartResults: {
      '10th': [40, 40, 40, 39, 39, 38, 38, 38, 38, 38],
      '90th': [44, 44, 44, 45, 45, 46, 46, 46, 47, 47],
      'avg': [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
  {
    seatChartResults: {
      '10th': [41, 40, 40, 39, 39, 39, 38, 38, 38, 38],
      '90th': [43, 44, 45, 45, 45, 46, 46, 46, 47, 47],
      'avg': [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
];

const res = Array.from(data.reduce((acc, {seatChartResults}) => { // add corrsponding array entries
      Object.entries(seatChartResults).forEach(([k, arr]) => {
        acc.set(k, arr.map((n, i) => ((acc.get(k) || [])[i] || 0) + n));
      });
      return acc;
    }, new Map()).entries())
    .reduce((acc, [k, arr]) => { // compute average
      acc.seatChartResults[k] = arr.map(n => n / data.length);
      return acc;
    }, {seatChartResults: {}});

console.log(res);

答案 1 :(得分:1)

您未在最终通话中返回allKeys

但是无论如何,您的实现都不会返回您真正想要的。

请记住,使用函数数组方法时,始终需要返回。

您的代码的有效版本可以是:

/**
 * Return average of array with key `seatChartResults`
 *
 * @param data  The data provided
 */
function average( data ) {
    return {
        seatChartResults : data
            .reduce( ( acc, { seatChartResults }, i, arr ) => (
                Object
                    .keys( seatChartResults )
                    // Each key will replace the reduced accumulator object
                    .reduce( ( acc, key ) => Object.assign( acc, {
                        [key] : seatChartResults[key]
                            // The key will be replaced with the summed arrays
                            // If the accumulated key does not exist it will be
                            // initialized with []. If the accumulated value of the index
                            // in this key does not exist it will be initialized with
                            // 0
                            .map( ( v, i ) => (acc[key] ? (acc[key][i] || 0) : 0) + v )
                            // If it is the last object we divide by the amount of
                            // objects to get the average
                            .map( sum => i === arr.length - 1 ? sum / arr.length : sum )
                    } ), acc ) // <--- Note we use acc as our initial reducer value
            ), {} )
    };
}

const data = [
  {
    seatChartResults: {
     '10th': [40, 40, 40, 39, 39, 38, 38, 38, 38, 38],
     '90th': [44, 44, 44, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
  {
    seatChartResults: {
     '10th': [41, 40, 40, 39, 39, 39, 38, 38, 38, 38],
     '90th': [43, 44, 45, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  }
]

console.log( average( data ) );

答案 2 :(得分:0)

您仍然可以通过循环获得结果

const data = [
  {
    seatChartResults: {
     '10th': [40, 40, 40, 39, 39, 38, 38, 38, 38, 38],
     '90th': [44, 44, 44, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
  {
    seatChartResults: {
     '10th': [41, 40, 40, 39, 39, 39, 38, 38, 38, 38],
     '90th': [43, 44, 45, 45, 45, 46, 46, 46, 47, 47],
      avg: [42, 42, 42, 42, 42, 42, 42, 42, 42, 42],
    }
  },
];
const output = data[0];
const keys = Object.keys(data[0].seatChartResults);
for ( let i = 0 ; i < keys.length ; i++) {
for ( let j = 0 ; j < data[0].seatChartResults[keys[i]].length ; j++) {

output.seatChartResults[keys[i]][j] = (data[0].seatChartResults[keys[i]][j] + data[1].seatChartResults[keys[i]][j])/2;
}
}

console.log(output);