Manipulating information from one format to another

I am currently tackling the task of calculating scores based on departments within groups. For simplicity, I will focus on just one group as an example.

Here is the data structure that I have:

const data = [{
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 80,
            "count": 1,
            "department": "Engineering",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 40,
            "count": 1,
            "department": "Executive",
            "group": "Group one"
        },
        ... (additional data entries)
    ];

My goal is to construct a data structure for a heatmap:

const heatmapData = [
{
  row: 'Group one',
  columns: [
    { 
      name: 'Engineering', 
      averageScore: 70,  
    },
    { 
      name: 'Supporting Department', 
      averageScore: 100,  
    },
    .... (more unique departments)
  ]
}
]

I am struggling to find a straightforward solution for grouping data and performing calculations. Any assistance or guidance would be greatly appreciated. Thank you!

Answer №1

To organize your data, group it by the group attribute. Then, for each group, further categorize it based on the department and calculate the total score and count. Once you have this structure, you can compute the average score for each department.

const data = [{ "id": "cklt7ln1k0922o0sabjkk74m9", "score": 80, "count": 1, "department": "Engineering", "group": "Group one" }, { "id": "cklt7ln1k0922o0sabjkk74m9", "score": 40, "count": 1, "department": "Executive", "group": "Group one" }, { "id": "cklt7ln1k0922o0sabjkk74m9", "score": 40, "count": 1, "department": "OOO Boost", "group": "Group one" }, { "id": "cklt7ln1k0922o0sabjkk74m9", "score": 60, "count": 1, "department": "Engineering", "group": "Group one" }, { "id": "cklt7ln1k0922o0sabjkk74m9", "score...
// Code continues with data manipulation
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

To organize elements into a dictionary, you can use the following code snippet:

let organizedData = data.reduce((accumulator, value) => {
  if(!accumulator[value.category]) accumulator[value.category] = {};
  if(!accumulator[value.category][value.section]) accumulator[value.category][value.section] = {total: 0, count: 0, avgScore: 0};
  accumulator[value.category][value.section] = {
    total: accumulator[value.category][value.section].total + value.score,
    count: accumulator[value.category][value.section].count + 1,
    avgScore: (accumulator[value.category][value.section].total + value.score) / (accumulator[value.category][value.section].count + 1)
  }
return accumulator
}, {});

Next step is to transform it into the requested format:

Object.keys(organizedData).map(category => {
  return {
    category: category,
    sections: Object.keys(organizedData[category]).map(section => {return {name: section, avgScore: organizedData[category][section].avgScore}})
  }
})

Answer №3

Let me break down how this solution functions.. Considering that objects act more as pointers than values, I leveraged this concept in my approach. I utilized an array to store data (where new elements are added), along with 2 Objects to manage values (modifying these Objects directly impacted the "values" in the array). By populating the array with values linked to these Objects, I was able to structure the data according to your specified format.

UPDATED ONCE MORE.. I incorporated the logic from your calculation examples >:D

function group(array){
  let arr=[]; let groups={}; let departments={}
  array.forEach(a=>{
    if(!groups[a.group]){ //defining each group
      groups[a.group]={row:a.group,columns:[]}
      arr.push(groups[a.group])
    }
    if(!departments[a.department]){ //establishing each department
      departments[a.department]=[{name:a.department,averageScore:a.score*a.count},a.count] //score * count and count(based on your calculation examples)
      groups[a.group].columns.push(departments[a.department][0])
    }
    else{ //updating existing departments
      departments[a.department][1]+=a.count //count
      departments[a.department][0].averageScore+=a.score*a.count //score * count
      //(based on your calculation examples)
    }
  })
  Object.keys(departments).forEach(a=>departments[a][0].averageScore/=departments[a][1])
  return arr
}

console.log(group(data))
<script>
//to retain unnecessary space in the answer
window.data = [{
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 80,
            "count": 1,
            "department": "Engineering",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 40,
            "count": 1,
            "department": "Executive",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 40,
            "count": 1,
            "department": "OOO Boost",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 60,
            "count": 1,
            "department": "Engineering",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 100,
            "count": 2,
            "department": "Supporting Department",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 20,
            "count": 1,
            "department": "Designers",
            "group": "Group one"
        },
        {
            "id": "cklt7ln1k0922o0sabjkk74m9",
            "score": 20,
            "count": 1,
            "department": "Executive",
            "group": "Group one"
        }
    ];
</script>

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

The formatting in vscode does not apply to .tsx files

For a while now, I've relied on the Prettier extension in Visual Studio Code for formatting my code. However, since switching to writing React with Typescript, I now need to configure Prettier to format .tsx files accordingly. ...

Ensure Rxjs waits for the completion of the previous interval request before moving forward

Scenario: It is required to make an API call every 3 minutes to update the status of a specific service within the application. Here is my existing code snippet: interval(180000) .subscribe(() => this.doRequest ...

Adjust webpage display with JavaScript

Utilizing the mobile-first approach of Zurb Foundation, I successfully created a responsive design. However, my client now requires a direct link labeled "View desktop version" in the footer for when the website is accessed on mobile devices or tablets. T ...

Looking for assistance with navigating through this URL using Python (requests, beautifulsoup, or selenium) or Javascript (node js, puppeteer)?

While attempting to gather data, I encountered an interesting pagination challenge on the following URL: My expertise in Web Scraping was put to the test as this website implemented a unique JavaScript-driven pagination. For the initial 5 pages, it simply ...

Is it possible to generate a new union type by extracting values from an existing union type?

type Cartoon = { kind: 'cat', name: 'Tom'} | { kind: 'mouse', name: 'Jerry' } type Animal = 'cat' | 'mouse' // I am trying to figure out how to create the type Animal based on the values of kin ...

What is the proper method to trigger a re-render of a React functional component with the useEffect

Within my top-level component, I am utilizing a library to determine if a user’s browser is in light or dark mode. This information is then used to set the theme for the application, which includes HTML Canvas elements (it's crucial to note that the ...

Tips for activating text selection in PDF.js

Struggling to enable text selection in PDF.js after successfully displaying a PDF? Seeking a simple example to guide you through the process? Despite trying various approaches, I haven't achieved the desired outcome yet. My current code snippet is a ...

Iframe form submissions

I am interested in accomplishing the following task. My objective is to submit a form to my booking engine and show the results on either a new page or within a Div element. Ideally, when the user clicks the submit button, it would display an Iframe or re ...

The view fails to update when the object is modified

Within the acceptRequest function in child.component, the commissioner.requestAccepted property is set to false, and then the updated commissioner object is returned. Ideally, I want the button to be automatically removed from the view once the object is ...

Tips for refreshing a GET request within a Vue.js application

I am receiving data from my Rails API backend and I would like to automatically refresh that GET request every 15 seconds. This way, if there are any changes on the backend (for example, if a POST request is made to another route), it will reload and retri ...

Modify the contents of a textbox by editing the text as you type

Text within the text box follows this format: login -u username -p password When entering this text, I want to substitute 'password' with a series of '*'s equal in length. For example: 'login -u <a href="/cdn-cgi/l/email-prot ...

JavaScript: Employ array destructuring for improved code readability (eslintprefer-destructuring)

How can I resolve the ESLint error that says "Use array destructuring. eslint(prefer-destructuring)"? The error occurs on this line of my code: let foo = 1; foo = obj.data[i][1]; //ESLint error on this line If anyone could provide assistance in fixing thi ...

Creating an optimized dashboard in Next.js: Expert tips for securing pages with specific roles, seamlessly implementing JWT authentication without any distracting "flickering" effect

Given our current setup: We have a backend ready to use with JWT authentication and a custom Role-Based Access Control system There are 4 private pages specifically for unauthenticated users (login, signup, forgot password, reset password) Around 25 priva ...

Exploring the Bookmarking Capabilities of Firefox

Is there a way to access the users' bookmarks using Firefox API and javascript? Appreciate any help, Bruno ...

increasing the size of the input thumb compared to the others

Hello fellow React developers, I'm currently learning by coding and I have a question about a slider. I'm trying to make the thumb of the slider bigger, but when I increase its size it doesn't fully display within the input area (as you can ...

Tips for adding new elements to an array within an object

Here is a snippet of my current JSON data: { "_id" : 393, "item" : 34, "comments" : [ { "name" : "kevin", "messages" : [ "item", "item" ] }, { ...

What is the best way to modify a current state object without causing an endless loop of redirects?

const useCase = (argument) => { const [value, setValue] React.useState(argument) React.useEffect(() => setValue({...value ...argument), [argument, value, setValue]) } The above code is currently causing an infinite loop due to setting the stat ...

What are the methods to transmit various data formats in an AJAX POST request?

I am facing an issue with sending a JSON object along with two file upload objects to the controller in JavaScript. I have tried the following code snippet: data: {"jsonString":jsonString, "fd":"fd", "fd1":"fd1"}, Is there any other way to achieve this, ...

Maintaining the user interface state while utilizing $resources in AngularJS

For my app, users have the ability to create and delete items. I've implemented $resources for this functionality, which is working really well. However, I'd like to implement a loading screen that appears whenever a request is being processed. ...

Top method for showcasing animated images (HTML/CSS/JS)

For my website, I want to create an engaging animation showing a coin being flipped multiple times in the air before landing on a specific side. After the animation finishes, I would like it to transform into a static image of the final result. I've ...