简体   繁体   English

迭代数据的javascript对象并找到平均值的最佳方法

[英]Best way to iterate a javascript object of data and finding the average

I am trying to iterate an object and display the average for each key inside the object. 我正在尝试迭代一个对象,并显示该对象内每个键的平均值。

Say I have: 说我有:

data = {
  totals: {
    item1: {
      time: 15,
      speed: 20,
      amount: 12,
      units: 29
    },
    item2: {
      time: 3,
      speed: 75,
      amount: 14,
      units: 3
    },
    item3: {
      time: 19,
      speed: 4,
      amount: 44,
      units: 365
    }
  }
}

What is the best way to create an average of those values like this: 求出这些值的平均值的最佳方法是什么:

averages = {
  time: 12,
  speed: 33,
  amount: 40,
  units: 132
}

I know to divide the total of each key's value by the total items, but I am struggling to find a good way to iterate each item and add the totals up. 我知道将每个键的值的总和除以项目总数,但是我正在努力寻找一种迭代每个item并将总和相加的好方法。 The items will be dynamically created depending on the entries for each account. 将根据每个帐户的条目动态创建项目。

Is using a for .. in loop the best way? 使用for .. in循环是最好的方法吗? If so how would I use that to accomplish this? 如果是这样,我将如何使用它来完成此任务? something like below? 像下面的东西?

function findAverage() {
  const averages = {
    time: 0,
    speed: 0,
    amount: 0,
    units: 0
  }

  const totalItems = Object.keys(data.totals).length 

  for (item in data.totals) {
    averages.time += item.time;
    averages.speed += item.speed;
    averages.amount += item.amount;
    averages.units += item.units;
  }

  averages.time = averages.time / totalItems;
  averages.speed = averages.speed / totalItems;
  averages.amount = averages.amount / totalItems;
  averages.units = averages.units / totalItems;

  return averages;
}

Is there a better way to go about this problem? 有没有更好的方法来解决此问题? Am I totally off in what I am trying to do here? 我在这里想要做的事情完全放弃了吗?

Instead of loops you can use Object.keys and reduce method on array 可以使用Object.keys并减少array上的方法来代替循环

 function calculateAverage(totals) { const items = Object.keys(totals).reduce((result, item) => result.concat(totals[item]), []) const itemsCount = items.length; const metricsTotals = items.reduce((sums, item) => { sums.time += item.time sums.speed += item.speed sums.amount += item.amount sums.units += item.units return sums }, { time: 0, speed: 0, amount: 0, units: 0}) return Object.keys(metricsTotals).reduce((average, metric) => { average[metric] = Math.floor(metricsTotals[metric] / itemsCount) return average }, {}) } var data = { totals: { item1: { time: 15, speed: 20, amount: 12, units: 29 }, item2: { time: 3, speed: 75, amount: 14, units: 3 }, item3: { time: 19, speed: 4, amount: 44, units: 365 } } } const averages= calculateAverage(data.totals) console.log(averages) 

You could take the wanted properties and the object and iterate and take then part of the lnght for adding to the average. 您可以获取所需的属性和对象,然后进行迭代,然后取一部分长度加到平均值上。

 var data = { totals: { item1: { time: 15, speed: 20, amount: 12, units: 29 }, item2: { time: 3, speed: 75, amount: 14, units: 3 }, item3: { time: 19, speed: 4, amount: 44, units: 365 } } }, averages = {}, keys = ['time', 'speed', 'amount', 'units']; keys.forEach(function (k) { averages[k] = 0; }); Object.keys(data.totals).forEach(function (l, _, ll) { keys.forEach(function (k) { averages[k] += data.totals[l][k] / ll.length; }); }); // flooring if neccessary keys.forEach(function (k) { averages[k] = Math.floor(averages[k]); }); console.log(averages); 

So if you need more performance you have to use for loop. 因此,如果您需要更高的性能,则必须使用for循环。 For loop is faster then forEach and forEach is faster then for in loop. For循环比forEach更快,而forEach则比forEach更快。 Here you can find performance benchmarks https://jsperf.com/for-vs-foreach/75 在这里您可以找到性能基准https://jsperf.com/for-vs-foreach/75

This code as an example for unlimited amount of items and unlimited amount of values. 此代码作为无限制数量的项目和无限制数量的值的示例。

 "use strict"; let data = { totals: { item1: { time: 15, speed: 20, amount: 12, units: 29 }, item2: { time: 3, speed: 75, amount: 14, units: 3 }, item3: { time: 19, speed: 4, amount: 44, units: 365 } } }; let items = Object.keys(data.totals); let max = items.length; let keys = Object.keys(data.totals[items[0]]); let averages = {}; for (let i = 0, max = keys.length; i < max; i++) { averages[keys[i]] = 0; } for (let i = 0; i < max; i++) { for (let j = 0, max2 = keys.length; j < max2; j++) { averages[keys[j]] += data.totals[items[i]][keys[j]] || 0; } } for (let i = 0, max2 = keys.length; i < max2; i++) { averages[keys[i]] = Math.floor(averages[keys[i]]/max); } console.log(averages); 

Also topicstarter has a mistake 另外topicstarter有一个错误

averages = { time: 12, speed: 33, amount: 40, units: 132 } 平均值= {时间:12,速度:33,数量:40,单位:132}

amount value can't be 40 (12 + 14 + 44 => 70 / 3 = 23) 金额值不能为40(12 + 14 + 44 => 70/3 = 23)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM