如何循环特定键以获取它在对象数组中出现的次数。

huangapple go评论59阅读模式
英文:

How to loop for a specific key for the number of times it occurs in an array of objects

问题

我目前正在进行一个物联网项目,需要计算从某个时间点开始的15分钟窗口的平均值:

| 区块          | 平均值               |
| 00:00 - 00:15  | 这个区块的平均值     |
| 00:15 - 00:30  | 这个区块的平均值     |
| 00:30 - 00:45  | 这个区块的平均值     |
| 00:45 - 01:00  | 这个区块的平均值     |

以此类推。我已经实现了一个解决方案。流程如下:

物联网核心 - 规则引擎 - SQS队列 - Lambda函数(由CloudWatch定时作业触发,每小时的第15分钟运行一次)

我编写的Lambda代码用于计算有效负载中不同站点(设备)的数量,并为每个站点(设备)计算出现次数,因为我需要按照时间块的方式计算多个站点或设备的平均值。
以下是我为了测试函数而配置的测试事件:

[
  {
    "site_name": "adodar",
    "active-power": 23.4
  },
  {
    "site_name": "adodar",
    "active-power": 10.4
  },
  {
    "site_name": "adodar",
    "active-power": 2.4
  },
  {
    "site_name": "adodar",
    "active-power": 3.4
  },
  {
    "site_name": "adodar",
    "active-power": 11.4
  },
  {
    "site_name": "adodar",
    "active-power": 0.4
  },
  {
    "site_name": "jamanvada",
    "active-power": 6.4
  },
  {
    "site_name": "jamanvada",
    "active-power": 0.5
  },
  {
    "site_name": "jamanvada",
    "active-power": 4.55
  },
  {
    "site_name": "abcd",
    "active-power": 9.08
  }
]

以下是我用于计算每个站点出现次数的Lambda代码:

export const handler = async(event) => {
    // TODO implement
    let occurences = {};
    let arr = event;
    arr.map(data => {
        occurences[data.site_name] = (occurences[data.site_name] || 0) + 1;
    });
    console.log(occurences);
};

在这里,我得到了与预期相符的正确输出,用于计算每个设备或站点的记录数量,以下是我的输出:

 { adodar: 6, jamanvada: 3, abcd: 1 }

现在,我想循环处理每个站点或设备的次数,并计算平均值。
例如,设备adaodar有6次出现,所以公式是

将6个出现次数相加 / 每个站点的出现次数。

例如,adodar有6个实例,我想循环处理这6个对象,并计算“active-power”字段的平均值。

但是我无法实现这一点。

任何帮助将不胜感激。

英文:

I'm currently working on an iot project which needs to calculate the average of a 15 minute window starting from :-

| Blocks         | Average               |
| 00:00 - 00:15  | average of this block |
| 00:15 - 00:30  | average of this block |
| 00:30 - 00:45  | average of this block |
| 00:45 - 01:00  | average of this block |

and so on.I've implemented one solution. The flow goes in this manner.

> iot core -> rules engine -> sqs queue -> lambda function (triggered by cloudwatch cron job which runs it every 15th minute of the hour)

The lambda code I've is to count the number of distinct sites (devices) in the payload and calculate occurences for each of the site(devices) as i have to calculate average in time block fashion for multiple sites or devices
Here is my test event which i have configured for now to test the function :-

[
  {
    "site_name": "adodar",
    "active-power": 23.4
  },
  {
    "site_name": "adodar",
    "active-power": 10.4
  },
  {
    "site_name": "adodar",
    "active-power": 2.4
  },
  {
    "site_name": "adodar",
    "active-power": 3.4
  },
  {
    "site_name": "adodar",
    "active-power": 11.4
  },
  {
    "site_name": "adodar",
    "active-power": 0.4
  },
  {
    "site_name": "jamanvada",
    "active-power": 6.4
  },
  {
    "site_name": "jamanvada",
    "active-power": 0.5
  },
  {
    "site_name": "jamanvada",
    "active-power": 4.55
  },
  {
    "site_name": "abcd",
    "active-power": 9.08
  }
]

Here is my lambda code to count the number of occurence for each site:-

export const handler = async(event) => {
    // TODO implement
    let occurences = {};
    let arr = event;
    arr.map( data => {
	  occurences[data.site_name]=(occurences[data.site_name] || 0)+1;
    });
    console.log(occurences);
};

Here i get the correct output as expected to count the number of records for each device or site, here is my output:-

 { adodar: 6, jamanvada: 3, abcd: 1 }

Now I want to loop for each site or device for as many times as the number of occurences and calculate the average for that.
For instance, device adaodar has 6 occurences so formula is

add all 6 occurences / number of occurences for each site.

For instance adodar has 6 instaces i want to loop over those 6 objects and calculate the average of "active-power" field.

But i'm unable to achieve this.

Any help would be greatly appreciated.

答案1

得分: 1

你应该能够通过存储每个站点的active-power总和和计数来计算平均值:

export const handler = async (event) => {
  let occurences = {};
  event.forEach(data => {
    if (occurences[data.site_name] === undefined) {
      occurences[data.site_name] = {
        activePowerSum: 0.0,
        count: 0
      };
    }
    occurences[data.site_name].activePowerSum += data['active-power'];
    occurences[data.site_name].count++;
  });
  let averages = {};
  for (const key in occurences) {
    averages[key] = occurences[key].activePowerSum / occurences[key].count;
  }
  console.log(occurences, averages);
};
英文:

You should be able to calculate the averages by storing the active-power sum and count for each site:

export const handler = async (event) => {
  let occurences = {};
  event.forEach(data => {
    if (occurences[data.site_name] === undefined) {
      occurences[data.site_name] = {
        activePowerSum: 0.0,
        count: 0
      };
    }
    occurences[data.site_name].activePowerSum += data['active-power'];
    occurences[data.site_name].count++;
  });
  let averages = {};
  for (const key in occurences) {
    averages[key] = occurences[key].activePowerSum / occurences[key].count;
  }
  console.log(occurences, averages);
};

答案2

得分: 0

我已经使用 occurences 取得了 occurences 的值,并使用 map 迭代数组中的每个值,然后通过其长度来除以值的总和:

> siteValues = {}
> Object.keys(occurences).forEach(key => { siteValues[key] = array.filter(x=>x.site_name==key).map(value => value['active-power'])});
undefined
> siteValues
{
  adodar: [ 23.4, 10.4, 2.4, 3.4, 11.4, 0.4 ],
  jamanvada: [ 6.4, 0.5, 4.55 ],
  abcd: [ 9.08 ]
}

为了获取每个站点名称的总和,我使用了 reduce,然后再次使用 array.filter 进行数组长度的除法运算(可能有一些额外的计算操作):

> Object.keys(occurences).forEach(key => { siteValues[key] = array.filter(x=>x.site_name==key).map(value => value['active-power']).reduce(function(a, b) { return a + b; }, 0) / array.filter(x=>x.site_name==key).length});
undefined
> siteValues
{
  adodar: 8.566666666666665,
  jamanvada: 3.8166666666666664,
  abcd: 9.08
}

这等同于:{ adodar: 51.39999999999999 / 6, jamanvada: 11.45 / 3, abcd: 9.08 / 1 }

英文:

I have took occurences and iterate through each value in array using map and divide the sum of values by his length:

> siteValues = {}
> Object.keys(occurences).forEach(key => { siteValues[key] = array.filter(x=>x.site_name==key).map(value => value['active-power'])});
undefined
> siteValues
{
  adodar: [ 23.4, 10.4, 2.4, 3.4, 11.4, 0.4 ],
  jamanvada: [ 6.4, 0.5, 4.55 ],
  abcd: [ 9.08 ]
}

to get the sum of each site name i have used reduce and divide between array length using again array.filter (maybe have some extra calulation operations):

> Object.keys(occurences).forEach(key => { siteValues[key] = array.filter(x=>x.site_name==key).map(value => value['active-power']).reduce(function(a, b) { return a + b; }, 0) / array.filter(x=>x.site_name==key).length});
undefined
> siteValues
{
  adodar: 8.566666666666665,
  jamanvada: 3.8166666666666664,
  abcd: 9.08
}

which is equivalent to: { adodar: 51.39999999999999 / 6, jamanvada: 11.45 / 3, abcd: 9.08 / 1 }

huangapple
  • 本文由 发表于 2023年1月7日 14:54:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75038599.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定