Incorporating a fresh attribute into a javascript object

We start with an array that includes the following data structure:

array = [{
 key: '2001',
 values: [
  { id : '123a', points: 3, hours: 3 },
  { id : '123a', points: 4, hours: 2 },
  { id : '4444', points: 3, hours: 2 },
  { id : '4444', points: 3, hours: 5 },
]
}, {
 key: '2002',
 values: [
 { id : '12d3a', points: 5, hours: 2 },
 { id : '12w3a', points: 3, hours: 3 },
]
}]

Using a function consisting of various Ramda functions, we managed to organize the data as follows:

const {map, evolve, pipe, groupBy, prop, pluck, sum, toPairs, zipObj} = R;

const a = map(evolve({
        values: pipe(
            groupBy(prop('id')),
            map(pluck('hours')),
            map(sum),
            toPairs,
            map(zipObj(['id', 'hours']))
        )
    }))

After this organization, we have gathered all "hours" for each id under each key (2001, 2002..) in the array.

The next step is to calculate and add another value named 'sum' to each object. The formula for calculating 'sum' is (points * hours) / (total sum of hours).

Do you have any ideas on how I can achieve this? I tried to modify the const a function but was unsuccessful. Is there another method or approach that can help me perform this operation using Ramda?

array = [{
 key: '2001',
 values: [
  { id : '123a', hours: 5, sum: 3.4 },
  { id : '4444',  hours: 7, sum: 3 }....

Answer №1

Check out this Ramda implementation that utilizes a reduction method to transform the data into an intermediate structure before converting it to the desired format:

const {map, evolve, pipe, groupBy, prop, reduce, values} = R;

const array = [{"key": "2001", "values": [{"hours": 3, "id": "123a", "points": 3}, {"hours": 2, "id": "123a", "points": 4}, {"hours": 2, "id": "4444", "points": 3}, {"hours": 5, "id": "4444", "points": 3}]}, {"key": "2002", "values": [{"hours": 2, "id": "12d3a", "points": 5}, {"hours": 3, "id": "12w3a", "points": 3}]}]

const transformedData = map(evolve({
  values: pipe(
    groupBy(prop('id')),
    map(reduce(
      ({totalPoints, totalHours}, {id, points, hours}) => ({id, totalPoints: totalPoints + points * hours, totalHours: totalHours + hours})
      , {totalPoints: 0, totalHours: 0}
    )),
    values,
    map(({id, totalHours, totalPoints}) => ({id, hours: totalHours, sum: totalPoints/totalHours})),
  )
}))

console.log(transformedData(array))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

Answer №2

Check out the following:

var data = [{
 key: '2001',
 values: [
  { id : '123a', points: 3, hours: 3 },
  { id : '123a', points: 4, hours: 2 },
  { id : '4444', points: 3, hours: 2 },
  { id : '4444', points: 3, hours: 5 },
]
}, {
 key: '2002',
 values: [
 { id : '12d3a', points: 5, hours: 2 },
 { id : '12w3a', points: 3, hours: 3 },
]
}];

data.forEach((entry) => {
  var map = {};
  entry.values.forEach((obj) => {
    map[obj.id] = map[obj.id] || [];
    map[obj.id].push(obj);
  });
  var processedValues = [];
  Object.values(map).forEach((vals) => {
    var totalPoints = 0, totalHours = 0;
    vals.forEach((val) => {
      totalPoints += val.points * val.hours;
      totalHours += val.hours;
    });
    processedValues.push({
      'id' : vals[0].id,
      'hours' : totalHours,
      'sum' : totalPoints/totalHours
    });
  });
  entry.values = processedValues;
});


console.log(data);

You may also want to consider this alternative approach:

data.forEach((entry) => {
  var map = {};
  entry.values.forEach((obj) => {
    map[obj.id] = map[obj.id] || {id : obj.id, totalPoints: 0, totalHours: 0};
    map[obj.id].totalHours += obj.hours;
    map[obj.id].totalPoints += (obj.points * obj.hours);
  });
  var processedValues = Object.values(map);
  processedValues.forEach((val) => {
    val.sum = val.totalPoints / val.totalHours;
    delete val.totalPoints;
  });
  entry.values = processedValues;
});

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

Leveraging NextJS to perform server side rendering by injecting parameters from a caller component

I'm currently in the process of creating an application with a storefront using nextJS. I've successfully utilized getServerSideProps when loading a new page. This particular page is quite complex, as it consists of multiple components, each req ...

Personalize the req.body object in Nodejs

I'm curious to know if it's possible to customize the req.body that is sent to MongoDB. Currently, my req.body looks like this: { f_name: 'John', l_name: 'Doe', phone: '4521234892345' } However, I would like it ...

Duplicate a Google Sheet and save it to a specific folder in Google Drive

I currently have two spreadsheets in my possession. The first spreadsheet consists of raw data that includes unique employee numbers and the names of the employees. The second spreadsheet is the one I aim to duplicate to a designated Google Drive folder. M ...

Issue with the display of Google reCaptcha verification popup within Mat Dialog

While working on an angular material dialog form, I integrated Google reCaptcha. However, when the reCaptcha verification popup appears, it displays above the form as shown in the image. https://i.sstatic.net/ax8QN.jpg I noticed that every time the mat d ...

Do we need to include the null character when declaring an array of characters?

In C, a string constant is represented as a character array. When creating this array element by element, it is important to include the null character. If I want to store the string constant S[number] = "hello\n" in C, I must remember that a string ...

Improving Zen Coding to integrate with JavaScript files on Sublime Text2

Sublime Text2 is hands down my go-to editor, except for one minor hiccup - the Zen Coding plugin only works with CSS and HTML files. There are plenty of times where I'd love to use Zen Coding with JavaScript or other file types, like incorporating HTM ...

Can the value in a JavaScript object be updated dynamically when a button is clicked?

In my JavaScript code, there is an object named annualPlan. Whenever a user submits the HTML form for a specific month, I aim to update the value in the object for that particular month accordingly. For instance, if someone submits August 21 and 200, I w ...

Is there a different way to retrieve data in Node.js instead of using mysqli

<?php $connect = mysqli_connect('localhost', "root", "", "test"); if(!$connect){ die(mysqli_connect_error()); } $sql = "SELECT * FROM articles"; $result = mysqli_query($connect, $sql) or die ...

What is the most efficient way to transfer a large search results array between NodeJS and AngularJS?

My application is built with NodeJS for the back-end and AngularJS for the front-end. I've run into an issue where sending a search query from Angular's $http to the back-end results in a bottleneck when there is a slow internet connection. Angul ...

Tips for successfully parsing JSON data during an Ajax call

After making an Ajax call, the response.responseText I receive looks like this: . "[ columns :[ { "id":"name", "header":"User name" }, { "id":"birth", "header":"Date of birth" } ], ...

How to send a JSON Object and a CSV file using FormData

I need to send a JSON Object and a CSV file in a fetch request from my frontend to my backend. The JSON object is stored in the headerIngestion variable, while the CSV file is saved in the csv state. let formData = new FormData(); formData.append('h ...

Printing a grid vector in C++: the ultimate guide

I am currently working on printing vectors in a grid using C++. My task is to populate a vector with random numbers in a 3x * 3y size and then display them as a two-dimensional matrix with a single array. I'm having trouble figuring out how to represe ...

Utilizing streams for file input and output operations in programming

This unique piece of code allows for real-time interaction with a file. By typing into the console, the text is saved to the file and simultaneously displayed from it. I verified this by manually checking the file myself after inputting text into the cons ...

What is the process for testing promise functions that contain an internal promise using Jasmine in an Angular environment?

In my service function, here's how it looks: asyncGetStuff: (id) -> stuff = [] @asyncGetItem id .then (item) -> #parse some data stuff.push data return stuff Now I am trying to verify the contents of 'stuff': ...

Utilizing Draft JS to dynamically insert text in the form of span

I'm utilizing Draft.js with its mentions plugin. Occasionally, I'd like users to input a mention not by choosing from a dropdown menu, but by typing something like, for example, "@item" or "@item". In the function below, you can observe that if ...

Executing a TypeScript function directly in HTML without the need for a click event

I understand how to trigger a TypeScript function when clicking a button, but how can I initiate a function without relying on a specific event? My goal is to call a function once an array named chartData has been populated. Here is the code snippet I have ...

Calculating the sum in a VueJS pivot table

Currently, I am delving into VueJS and working on migrating a basic application from Laravel with the blade template engine. The backend remains unchanged, consisting of a straightforward RESTful API with 3 tables: Books, Places, and a pivot table named B ...

Do not apply tailwindcss styles to Material-UI

I've been struggling to apply styling from tailwindcss to my MUI button. My setup includes babel and webpack, with the npm run dev script as "webpack --mode development --watch". tailwind.css module.exports = { content: ["./src/**/*.{js, jsx, t ...

Ensure that the module is exported before the Node.js file completes its execution using the `import`/`export` syntax

In the process of developing an API with express, my objective is to have a separate file for each endpoint. The idea is to create the router in its own file, export it, and then import the endpoint files to be executed. These endpoint files will import th ...

What is the best way to delete the initial element in a pointer array?

I am attempting to create a function called Remove_Item that takes a pointer array and the length of the array as parameters, and removes the first pointer in the array. Below is the code snippet: #include <stdio.h> #include <stdlib.h> void ...