Mean value calculated for each hour within a given array

Every minute, my array updates. To show the daily average of each hour, I need to calculate the average for every 60 elements.

The latest minute gets added at the end of the array.

    // Retrieving the last elements from the array
    var hours = (this.today.getHours() + 1) * 60
    var data = Array.from(this.temps.data)
    let lastData = data.slice(Math.max(data.length - hours))

    let newData: any

    // Calculating the hourly averages
    for (let i = 0; i < minutes; i++) {
      var cut = i * 60
      for (let j = cut; j < (cut + 60); j++) {
        newData = newData + lastData[j];
        let test = newData/60
        console.log(test);
      }
    }

I'm unsure how to create an array from the last 60 elements. My aim is to have an array like:

avgHour[20,22,30,27,]

The array I currently have is updated every minute, so I require the average of every 60 elements to represent an hour.

This array looks something like:

data[25,33,22,33]

Given that it represents every minute over a week, the array is quite lengthy.

This Solution Worked for Me

    var arrays = [], size = 60;

    while (arr.length > 0){
        arrays.push(arr.splice(0, size));
    }

    for (let i = 0; i < (arrays.length - 1); i++) {
      var sum = 0
        for (let b = 0; b < 60; b++) {
          sum += arrays[i][b]
        }
        let avg = sum/60
        arr2.push(avg)            
    }

This code essentially divides the array into smaller chunks of 60 elements each. This allows me to compute the average for each set of 60 elements.

Grateful for the assistance!

Answer №1

I have a strong admiration for the functional programming library known as Ramda, of which I happen to be one of the creators. My approach usually revolves around using simple, reusable functions.

When faced with a problem, my mind immediately turns to Ramda for a solution. Here is how I would tackle this particular issue:

const avgHour = pipe(
  splitEvery(60),
  map(mean),
)

// generating some random data
const data = range(0, 7 * 24 * 60).map(_ => Math.floor(Math.random() * 20 + 10))

console.log(avgHour(data))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {pipe, splitEvery, map, mean, range} = R</script>

After understanding that each function in the pipeline passes its result to the next one, I find this code snippet quite readable.

While it may seem unnecessary to incorporate a large library like Ramda for a simple task, the easily reusable nature of the functions used here makes it worthwhile. Creating your versions of these functions can be beneficial for your application, much like how libraries such as Ramda are developed.

Here's an alternative version showcasing straightforward implementations of these functions, ideal for inclusion in a utility library:

const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x)
const splitEvery = (n) => (xs) => {
  let i = 0, a = [] 
  while (i < xs.length) {a.push(xs.slice(i, i + n)); i += n}
  return a
}
const map = (fn) => (xs) => xs.map(x => fn(x))
const sum = (xs) => xs.reduce((a, b) => a + b, 0)
const mean = (xs) => sum(xs) / (xs.length || 1)

const avgHour = pipe(
  splitEvery(60),
  map(mean)
)

const range = (lo, hi) => [...Array(hi - lo)].map((_, i) => lo + i)

// generating some random data
const data = range(0, 7 * 24 * 60).map(_ => Math.floor(Math.random() * 20 + 10))

console.log(avgHour(data))

Answer №2

To simplify the data, you can group it by hour and then calculate the average for each hour. In this code snippet, I have used moment.js to handle date parsing, but feel free to use any other library or JavaScript function that you prefer.

const arr = Array.from({length: 100}, () => ({time: moment().subtract(Math.floor(Math.random() * 10), 'hours'), value: Math.floor(Math.random() * 100)}));
    
const grouped = [...arr.reduce((a, b) => {
    let o = a.get(b.time.get('hour')) || {value: 0, qty: 0};
    a.set(b.time.get('hour'), {value: o.value + b.value, qty: o.qty + 1});
    return a;
}, new Map)].map(([k, v]) => ({
    [k]: v.value / v.qty
}));

console.log(grouped)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>

Answer №3

To achieve this, you can group the data first and then reduce it in the following way:

function groupBy(list, keyGetter) {
  const map = {};
  list.forEach((item) => {
    const key = keyGetter(item);
    if (!map[key]) {
      map[key] = [item];
    } else {
      map[key].push(item);
    }
  });
  return map;
}

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];

const now = (new Date()).getTime();

const stepSize = 60000*1;

const withTime = data.reverse().map((x, i) => { return { time: new Date(now - stepSize * i), temp: x } });

const grouped = groupBy(withTime, x => new Date(x.time.getFullYear(), x.time.getMonth(), x.time.getDate(), x.time.getHours()).valueOf());


const avg = Object.entries(grouped).map((x) => {
  return {
    time: new Date(Number(x[0])),
    temp: x[1].map(y => y.temp).reduce((acc, val) => acc + val) * (1.0 / x[1].length)
  }
});

console.log(avg);

Answer №4

Breaking down the array into chunks of 60 elements was crucial to calculating the average effectively. Here is how I managed to tackle this challenge:

// Calculate the average of every 60 elements to determine the hourly average
var arr2: number[] = []
var arr: number[] = []
arr = Array.from(this.temps.data)
var arrays = [], size = 60;

while (arr.length > 0){
    arrays.push(arr.splice(0, size));
}

for (let i = 0; i < (arrays.length - 1); i++) {
  var sum = 0
    for (let b = 0; b < 60; b++) {
      sum += arrays[i][b]
    }
    let avg = sum/60
    arr2.push(avg)            
}

In retrospect, extracting the last elements of the array seems unnecessary in comparison to this improved solution. Many thanks for guiding me through this process!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using jQuery to restrict the occurrence of Ajax POST requests to once every 10 seconds

I created an interactive wizard using HTML that displays multiple panels. Users can navigate through the panels using a Next button and there is also a Finish button available. Whenever the user clicks on the next button, I have set up a click handler to s ...

Mastering Vue3: Typed Component Instance Template Refs with Exposed Methods

In my project, I am working with a component called A that has a method called send. Here is an example of how Component A is structured in A.vue: <script setup lang="ts"> function send(data: string) { console.log(data) } defineExpose({ ...

Using Angular and Jasmine: techniques for simulating a service that provides a promise

In my AngularJS application, I have a controller called MenuCtrl that utilizes a service provided by "$mdSidenav" from Angular Material. This service is created using a factory method. angular.module('leopDirective', []) .controller('Me ...

Proper method of managing undeclared declaration files (index.d.ts)

I encountered the following error message: error TS7016: Could not find a declaration file for module 'react-native-camera'. '/Users/ilja/Documents/Repositories/blok/node_modules/react-native-camera/index.js' implicitly has an 'an ...

Is there a way to verify if a component contains a child node with the tag <template></template>?

Consider the scenario with MyComponent: <div [my-component]="'text'"></div> Within the code, I have access to this.viewContainerRef, which refers to the DOM node itself (<div>). However, for customization purposes, a user mig ...

The following middleware is not functioning properly on a local SSL server

When I run my Nextjs app without SSL using "next dev", the middleware functions as expected without any errors. However, if I attempt to run the app with SSL enabled, an empty middleware function triggers an error. The code for the middleware function (l ...

Turning spring form data into a JSON object via automation (with a mix of Spring, jQuery, AJAX, and JSON)

Recently, I've set up a spring form that utilizes ajax for submission. Here's an overview of my form... <form:form action="addToCart" method="POST" modelAttribute="cartProduct"> <form:input type="hidden" ...

Invoke a specific URL during an HTML5 upload

So I've got this code that allows for file upload via drag and drop using HTML5 in the browser. $(function(){ var dropbox = $('#dropbox'), message = $('.message', dropbox); dropbox.filedrop({ // Customizing upload settin ...

Encountering a 500 error within a Passport JS and React application

I'm currently developing a chat application using React, and I've hit a roadblock while trying to authenticate users. The axios post request is throwing a 500 error that seems to be elusive. Even when the correct credentials are entered for a use ...

jQuery functions not functioning properly when triggered by an event

I encountered an issue with my page using jQuery and Bootstrap. Everything was functioning properly until I tried calling a function on an event, which resulted in the console showing an error message saying $(...).function is not a function. For example: ...

Merge Razor with Ajax and JSON

I have been struggling to get the following components to work together without success. The goal is to populate the mediaId's combobox with respective values based on the selection in the target combobox. Currently, I am only simulating the values fo ...

Even though the rxjs imports are correctly set up, the 'map' property is not found on the 'Observable<Response>' type

I'm currently developing a MEAN stack application using Angular 2. Despite finding similar inquiries on StackOverflow, I've explored various solutions without success. While many suggest importing the entire rx/js library along with map or using ...

Tips for adding information to a PHP file

Previously, I used PHP to append form data to a JSON file. Currently, I am working on a PHP file instead of a JSON file with two parameters, as shown to users in the figure below. Image URL Link My Form: <form action="process.php" method="POST"> ...

Searching for an index of a value fails after functions have been anonymized

I recently created a basic javascript animation that involves swapping images on a carousel and fading them in and out. My goal is to generalize the functions so that I can repurpose them for other projects. While most of the animation is functioning corr ...

Issues arise when JQuery functions fail to execute

This unique program showcases a series of error messages that are designed to appear under specific conditions. These conditions are identified through PHP code, following which the essential JQuery script is echoed via PHP to display the messages. Initia ...

The JavaScript error occurred: TypeError - Unable to access the property 'map' as it is undefined

import Link from 'next/link' export const getStaticProps = async () => { const res = await fetch('https://jsonplaceholder.typicode.com/users'); const data = await res.json(); return { props: { ninjas: data } } } const ...

Children components are not re-rendered by React

I created a basic task manager, but I'm encountering issues when trying to manage all the data from a single point within the TaskManager component. Essentially, I have a TaskManager component that acts as the container for all the data. Within this ...

"Functionality requiring Javascript is not enabled following an AJAX call until the page is

I've created a system that can generate an online form page and send it to a printer. This system utilizes AJAX to extract data from an existing page and send it to a Java servlet. The servlet then constructs the HTML and sends it back, where it is d ...

Is there a way to access the directory of $object[""0""].projhours in AngularJS without triggering any syntax errors?

Being new to this, I am trying to retrieve the value of projhours from this directory in console.log() without encountering a syntax error. While right-clicking on the projhours directory in the Chrome console displays ($object[""0""].projhours), AngularJS ...

Encountering Uncaught Syntax Error when attempting a request with JSON parameters

Currently, I am using Fetch to send a post request to my server while including some additional information. Here's the code snippet: var rating = document.getElementById("rating"); var ratingValue = rating.innerHTML; fetch("/films",{ method: "po ...