JavaScript: A guide to calculating the average of a JSON array using certain criteria within the keys/fields

I have a scenario where I need to calculate the average values of specific keys in an array:

const users = [
  { name: 'Adam', age: 20, country: 'France', weight: 100 },
  { name: 'Adam', age: 28, country: 'Germany', weight: 100 },
  { name: 'Adam', age: 28, country: 'India', weight: 200 },
  { name: 'Adam', age: 40, country: 'France', weight: 200 },
  { name: 'Oliver', age: 28, country: 'France', weight: 200 }
];

The averaging should be done based on the keys 'name' and 'country' for the keys 'age' and 'weight'

output = [
  { name: 'Adam', age: 30, country: 'France', weight: 150 },
  { name: 'Adam', age: 28, country: 'Germany', weight: 100 },
  { name: 'Adam', age: 28, country: 'India', weight: 200 },
  { name: 'Oliver', age: 28, country: 'France', weight: 200 }
];

If certain keys are not defined, they should be removed during the calculation process:

In this case, averaging is based solely on the key 'name' for 'age' and 'weight'

output = [
  { name: 'Adam', age: 29, weight: 150 },
  { name: 'Oliver', age: 28, weight: 200 }
];

Answer №1

To streamline the data, you can categorize it based on specific keys and calculate the average values for each key within a group.

function getAverages(array, groupKeys, averageKeys) {
    var groups = {},
        result = [];

    array.forEach(o => {
        var key = groupKeys.map(k => o[k]).join('|'),
            group = groups[key];

        if (!group) {
            groups[key] = { count: 0, payload: {} };
            group = groups[key];
            averageKeys.forEach(k => group[k] = 0);
            groupKeys.forEach(k => group.payload[k] = o[k]);
            result.push(group.payload);
        }
        groups[key].count++;
        averageKeys.forEach(k => group.payload[k] = (group[k] += o[k]) / group.count);
    })
    return result;
}

const users = [{ name: 'Adam', age: 20, country: 'France', weight: 100 }, { name: 'Adam', age: 28, country: 'Germany', weight: 100 }, { name: 'Adam', age: 28, country: 'India', weight: 200 }, { name: 'Adam', age: 40, country: 'France', weight: 200 }, { name: 'Oliver', age: 28, country: 'France', weight: 200 }];

console.log(getAverages(users, ['name', 'country'], ['age', 'weight']));
console.log(getAverages(users, ['name'], ['age', 'weight']));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

If you want to achieve specific objectives, you can utilize functions such as filter, map, and reduce.

For ensuring the existence of keys, you can filter out entries that do not contain those keys:

// Filter out entries without the age property
const validUsers = users.filter(entry => entry.age)

To calculate the average age of all users, you can then streamline the filtered array using reduce to obtain a single value, which is then divided by the total length of the array. This operation can be executed in just one line of code.

const averageAge = users.filter(entry => entry.age).reduce((sum, entry) => sum + entry.age, 0) / users.length

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

Guide to handling HTTP request parsing in Express/NodeJs when the content type is missing, by setting a default content type

Is it possible to retrieve POST data in an express request when the bodyParser does not work? var server = express(); server.use(express.bodyParser()); server.post('/api/v1', function(req, resp) { var body = req.body; //if request header doe ...

Inconsistency in Numpy's handling of float promotion

I have always believed that in the equation x = f() * g(), the function f() is executed first, followed by g(), then the results are multiplied and assigned to x. However, the code below seems to challenge this assumption: import numpy as np print(np.sqrt ...

Issue with Material-UI Slider not updating the color of the active range

I am currently working on a Range Slider component that ranges from zero to ten. The issue I am facing is that the values inside the range are not getting colored as expected. Here is My Custom Slider Component: export function VoteRange({ voteRange, set ...

Transferring hyperlink text to a different page using Express JS

I'm currently dealing with a coding issue where I need to pass a link text within a hyperlink to another page. The web application is built using Express. On one of the pages, there's a dropdown list containing this hyperlink: <a class=" ...

Is it possible to extract data from a table by adjusting Javascript in the inspector tool? The page is only showing today's data, but I'm interested in retrieving historical data by going back

My Desired Action: I am interested in extracting data from the 2nd and 3rd tables on this page. However, the data displayed is specific to the current 'day'. I wish to access readings from September 1st and import them into a Google Sheet. Speci ...

Tips for arranging, categorizing, and separating the array in alphabetical order using Angular 2+

I am looking to organize the buttons' content alphabetically into groups A-H, I-Q, and R-Z. The code I'm using is in Angular2+. https://i.sstatic.net/pPCBO.png My array: this.dropdownList = [ { item_text: 'Organisation' }, ...

Looking for a simple method to extract file names from a directory and store them in an array?

I'm looking for a way to automate the process of creating links to mp3 files in a directory called Audio/. Is it possible to read the directory and add filenames to an array? It would be really neat if we could create an associative array where the ke ...

Maintain cookie persistence beyond browser shutdown

Using this code snippet in Node-Express JS, I am creating a cookie with a JWT token included. Here is the code: var token = jwt.sign(parsed.data, "token_secret", {expiresIn: "43200m"}); res.setHeader('Set-Cookie', 'token='+token+&apos ...

What is the best way to allow all authenticated routes to display the Devise ajax Login form?

I have successfully incorporated Devise to accept Ajax Login and have designed a form for logging in via ajax, displayed within a modal. However, I am only able to view the form and login when I set up event binders for specific buttons that activate the m ...

Waiting for data to be passed from a parent component within a method

I have a situation where I need to make an API call in my layout and send the received data as an object to my component. The problem arises because the object is empty when the method is called inside the mounted() function. Therefore, I want to execute ...

Removing the JavaScript unicode character 8206 from a text string

I recently transitioned from VB.NET to JavaScript, and I am still getting familiar with the language. I have encountered an issue where a string I'm working with in JavaScript contains Unicode escape characters (0x5206, left-to-right mark) that I need ...

Learn the process of updating a nested document within an array in MongoDB

I have a data structure as shown below: { "name":"xxxxxx", "list":[ { "listname":"XXXXX1", "card":[ { "title":"xxxxxx", "descip":"xxxxxxx ...

What is the best way to dynamically update cells within an HTML table row when a single column is changed?

My webpage features an HTML table that is dynamically constructed. Within this table, I have made some of the cells editable, with one cell containing a calculated value based on two other cells in the same row. Here is a snippet of my table: <tr class ...

Is there a way to identify when a fresh google instant page appears?

I am currently developing a browser extension that requires making a call when a new Google instant page is loaded and then modifying the results, similar to SEOQuake. One problem I encountered is that if a user pastes a link directly into the URL field a ...

Is it possible to detect individual key value modifications in Firestore using Angular?

getUserEventSummaryE(userId) { return docData(doc(this.firestore, `/user/${userId}/event_summary/current/`), {idField : 'playing_summary'}). pipe(distinctUntilChanged((prev, curr) => _.isEqual(prev, curr))); } getUserEventSummaryE functio ...

Having trouble with JQuery Ajax when trying to send multiple data at once?

name = "John Doe"; username = "johndoe123"; password = "secure123"; $.ajax({ type: 'POST', url: "https://example.com/api", data: { name: name, username: username, password: password }, success: function(response, status, xhr ...

How can one best parse information from intricate JSON documents for optimal efficiency?

As a newcomer to Python, I am currently focused on extracting specific information from dict files. My task involves dealing with millions of JSON files that store textual data, all sharing similar structures but with various nuances in terms of organizati ...

Retrieve the location of the selected element

We are faced with the challenge of determining the position of the button clicked in Angular. Do you think this is achievable? Our current setup involves an ng-grid, where each row contains a button in column 1. When the button is clicked, we aim to displ ...

How can I integrate custom PHP pages into Odoo Community 12?

I am looking for a way to integrate my custom PHP webpages with the login page of Odoo Community that is already set up and functioning on my server. I want specific users to be redirected to my custom pages after logging in. Any suggestions on how to ac ...

Using jQuery or Javascript to implement a drop-down list filter functionality

For the past two months, I've been struggling to figure out how to create a drop-down menu to filter content on the site I'm building for my boss. Despite countless searches online, I haven't found a solution that works. This is the only iss ...