A guide on organizing an array of objects by a specific property using a separate array

Here is the array I am working with:

var arr = [
  {
    count: 27,
    dataRil: "08/06/21",
    subCateg: "FISH",
  },
  {
    count: 22,
    dataRil: "08/06/21",
    subCateg: "DOG",
  },
  {
    count: 28,
    dataRil: "09/06/21",
    subCateg: "FISH",
  },
  {
    count: 18,
    dataRil: "09/06/21",
    subCateg: "DOG",
  },
  {
    count: 1,
    dataRil: "09/06/21",
    subCateg: "CAT",
  },
  {
    count: 1,
    dataRil: "09/06/21",
    subCateg: "BIRD",
  },
];

I need to group this array by category and extract the counts into a new array. How can I accomplish this?

The desired output should be:

var datasets = [
  {
    label: "FISH",
    data: [27, 28],
  },
  {
    label: "DOG",
    data: [22, 18],
  },
  {
    label: "CAT",
    data: [0, 1],
  },
  {
    label: "BIRD",
    data: [0, 1],
  },
];

Answer №1

Upon analyzing the issue at hand, our primary objective is to reformat the data based on date and extract all sub-categories before proceeding with the reformatting process.

Once the initial steps are completed, we can then retrieve the desired data from the updated and reformatted dataset.

const arr = [{
    count: 27,
    dataRil: "08/06/21",
    subCateg: "FISH",
},
{
    count: 22,
    dataRil: "08/06/21",
    subCateg: "DOG",
},
{
    count: 28,
    dataRil: "09/06/21",
    subCateg: "FISH",
},
{
    count: 18,
    dataRil: "09/06/21",
    subCateg: "DOG",
},
{
    count: 1,
    dataRil: "09/06/21",
    subCateg: "CAT",
},
{
    count: 1,
    dataRil: "09/06/21",
    subCateg: "BIRD",
}];
const dataOnDate = {};
const dataSet = [];
const subCateg = [];
function getFormatedData() {
    arr.forEach(er => {
        if (subCateg.includes(er.subCateg) === false) {
            subCateg.push(er.subCateg);
        }
        if (dataOnDate[er.dataRil] === undefined) {
            dataOnDate[er.dataRil] = {};
        }
        dataOnDate[er.dataRil][er.subCateg] = er.count;
    });
}
getFormatedData();
 

function extractData() {
    const dataSet = [];

    subCateg.forEach(cat => {
        let mid = {
            label: cat,
            data: []
        };
        Object.keys(dataOnDate).forEach(data => {
            if (dataOnDate[data][cat] !== undefined) {
                mid.data.push(dataOnDate[data][cat])
            } else {
                mid.data.push(0);
            }
        });
        dataSet.push(mid);
    });
    return dataSet;
}

const result = extractData();
console.log(result);

Answer №2

To transform it into an object, I utilized a traditional histogram technique before converting it back to an array...

var arr = [
  { count: 27, date: "08/06/21", category: "FISH" }, 
  { count: 22, date: "08/06/21", category: "DOG" }, 
  { count: 28, date: "09/06/21", category: "FISH" }, 
  { count: 18, date: "09/06/21", category: "DOG" }, 
  { count: 1, date: "09/06/21", category: "CAT" }, 
  { count: 1, date: "09/06/21", category: "BIRD" } 
]

let tempObj = {}

arr.forEach(item => {
  if (tempObj.hasOwnProperty(item.category)) {
    tempObj[item.category].data.push(item.count)
  } else {
    tempObj[item.category] = {data: [item.count]}
  }
})

let newArr = []

let longestDataArrayLength = 0

//identify the length of the longest data array
Object.keys(tempObj).forEach(key => {
  if (tempObj[key].data.length > longestDataArrayLength) longestDataArrayLength = tempObj[key].data.length
})

Object.keys(tempObj).forEach(key => {
  if (tempObj[key].data.length < longestDataArrayLength) {
    for (let i = tempObj[key].data.length; i < longestDataArrayLength; i++){
      tempObj[key].data.unshift(0)
    }
  }
})


Object.keys(tempObj).forEach(key => newArr.push({"label": key, "data": tempObj[key].data}))

console.log(newArr)

Interactive Code Editor

UPDATE: Included code to fill in shorter arrays

Answer №3

Perhaps this approach could be effective if you prefer not to have 0 in your data for the specific element. It's uncertain what significance 0 holds in your scenario, but this method may suit your needs.

UPDATE: The logic has undergone a revision. It appears that you intend to populate the remaining elements at the beginning with 0. The current solution involves filling the array of remaining length with 0 at the start.

    var initialArray = [{ count: 27, dataRil: "08/06/21", subCateg: "FISH" }, { count: 22, dataRil: "08/06/21", subCateg: "DOG" }, { count: 28, dataRil: "09/06/21", subCateg: "FISH" }, { count: 18, dataRil: "09/06/21", subCateg: "DOG" }, { count: 1, dataRil: "09/06/21", subCateg: "CAT" }, { count: 1, dataRil: "09/06/21", subCateg: "BIRD" } ];

    var arr = initialArray.reduce((accum,curr) => {
         if(accum[curr.subCateg] == undefined) {
           accum[curr.subCateg] =  {
              label: curr.subCateg,
              data : [curr.count] 
           };
           return accum;
         }
          let count = accum[curr.subCateg]['data'];
          count.push(curr.count);
          return accum;
        
    },{});

    var arr = Object.values(arr);
    var maxLength = arr.map(x => x.data.length).reduce((max, val) => max > val ? max : val);

    var result = arr.map((data) => {
      if(data.data.length < maxLength){
          let newarr = (new Array(maxLength - data.data.length));
          data.data = [ ...newarr.fill(0) , ...data.data];
      }
      
      return data;
    });
    console.log(initialArray);
    console.log("Result" , result);

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

Steps for formatting JSON objects for database storage with Node-orm2:

I have incorporated node-orm2 for saving a model to a MySQL database column. The functionality is excellent, but I am looking to achieve pretty printing of the written JSON data in order to improve readability when viewing the DB records. Is there a wa ...

What is the process for configuring my form to automatically send to my email upon clicking the send button?

I found this code snippet on a website and I'm trying to figure out how to make the 'Send!' button redirect users to my email address with their message, name, and email included. Can anyone help me solve this issue? I attempted to add my e ...

What is the best way to submit form data along with an image using Angular?

Recently, I built an application where users can submit form data along with an uploaded image. Since I am new to Angular, I am facing some challenges in merging the user-submitted data model and the image upload using the FormData method. Can anyone guide ...

Perform a Brute Force Rotation of the Array to the Right by K positions

While I was browsing through some coding problems on leetcode, I stumbled upon this particular question related to arrays. The issue seems to be arising from the shifting section within the provided code snippet. Example 1: Input: nums = [1,2,3,4,5,6,7], ...

"Is it possible to use a Twitter widget with Mootools

I have been attempting to create a marquee for my twitter Account on my website. After some trial and error, I was able to achieve this using jQuery. Here is the code I used: <div id="twitter"> <p> Loading.....</p> <n ...

Tips for managing the 'completed' button in an Android keyboard application using AngularJS/Ionic

Currently, I am working on developing a hybrid mobile application using AngularJS, Cordova, and the Ionic framework. Check out this Android 5.0 keyboard with a distinct blue button located at the bottom-right corner. https://i.stack.imgur.com/Tfija.png ...

How to format JSON using iisnode

Whenever I run my node.js application locally, I always receive JSON output that is nicely formatted with line breaks and spaces. It looks something like this: { "foo": "bar", "asdf": "qwerty" } However, when I execute the same code in iisnode on Azu ...

Splitting data in NodeJS sockets

Whenever I encounter the need to divide data, my standard practice involves converting it into a string format. Here's an example of how I handle data in my function: socket.on('data', function (data) { var str = data.toString().spl ...

Perform a Selenium action to click on each individual HTML 'a' tag on

I am attempting to automate clicking on all the "a" tags within a website using Selenium in Python. However, I found that all the "a" tags I want to click have the same structure as shown in the code snippet below. I tried clicking them by their class si ...

Redirecting script upon successful connection detection

I have created a script that checks for internet connectivity using an image, and redirects if internet is available. However, the issue is that it caches the images, leading to attempts to load them even when offline. Is there a different approach I can ...

Ways to include scrolling specifically for one template

As a newcomer to frontend development, I have recently started learning Vue and the Quasar Framework. I am currently working on a table and trying to set a fixed table name with only the table items scrollable. <template> <q-table virt ...

Using Typescript to pass a property as one of the keys in an object's list of values

In my React Native project, I need to pass a string value from one component to another. The different options for the value can be found in the ScannerAction object: export const ScannerAction = { move: 'move', inventory: 'inventory&apo ...

instructions for executing this javascript within the <p> tag

This is the code I have written : <p onload=javascript:alert('sss')>www</p> Unfortunately, the code does not alert 'sss', Can someone please tell me what's wrong with my code? Thank you ...

The issue persists with the addEventListener function not working multiple times

My issue is that the addEventListener function is only working for the 'scroll' event and not for 'addMoreFields' or 'removeFields'. If I move the scroll section down, then it works for 'addMoreFields' and 'remo ...

Utilize JQuery to Extract HTML Elements

I'm working on developing a Chrome extension and one of my tasks is to extract specific text from the webpage I am currently visiting and store it in a variable. I have been attempting to achieve this using jQuery, however, none of the solutions I&apo ...

JavaScript / html Error: function body missing closing curly brace

I encountered an error that I'm struggling to resolve: "SyntaxError: missing } after function body". Despite not having a function named 'body', I have attempted changing every instance of 'body' in my script. However, ...

Error encountered while testing karma: subscription function is not recognized

I encountered an issue with my karma unit test failing with the following error message. "this.gridApi.getScaleWidth().subscribe is not a function" GridApi.ts export class GridApi { private scaleWidthSubject = new BehaviorSubject<{value: number}& ...

Revamping array elements in React

Once I added an element to the array, I needed to update this array by doubling all elements except for the one that was just added. Despite trying setArray([]) before retrieving the array from the database, it didn't seem to work... const [array, se ...

Node.js and Express facing challenge with Stripe checkout functionality

I am encountering an issue while attempting to integrate stripe into my checkout process. When I click on the checkout button, instead of being directed to the checkout page, I receive the following message: {"url":"https://checkout.stripe.c ...

Error Encountered with CakePHP Model when Parsing AJAX JSON Data

I encountered a problem with AJAX while developing an application using CakePHP 2.5.3.0 My AJAX request from jQuery to CakePHP is meant to send the user's login and password, expecting a validated JSON response. However, when using a Model method wit ...