Reorganize a collection of objects to a more intricate structure

As I work on my project to create a table using basic HTML (JSX), I am faced with the challenge of displaying unique dates along with the quantity of apples, strawberries, bananas, and oranges sold each day.

The data obtained from the API is causing difficulties in structuring the table as needed, so I am looking to reorganize it.

const data = [
  {
    id: 1,
    date_sold: "2020-11-14",
    fruit: "Apples",
    amount: 9,
  },
  {
    id: 2,
    date_sold: "2020-11-14",
    fruit: "Strawberries",
    amount: 2,
  },
  // more data...
];

The objective is to transform the data into a format like this:

const newData = {
  "2020-11-14": { Bananas: 0, Apples: 9, Strawberries: 2, Oranges: 0 },
  "2020-11-13": { Bananas: 2, Apples: 1, Strawberries: 3, Oranges: 4 },
  // more transformed data...
};

Answer №1

To achieve this, you can utilize the Array.prototype.reduce method.

const records = [
  {
    id: 1,
    date_sold: "2020-11-14",
    fruit: "Apples",
    amount: 9,
  },
  {
    id: 2,
    date_sold: "2020-11-14",
    fruit: "Strawberries",
    amount: 2,
  },
  // more data here...
];

const result = records.reduce((accumulator, current) => {
  accumulator[current.date_sold] ? accumulator[current.date_sold][current.fruit] = current.amount : accumulator[current.date_sold] = {
    [current.fruit]: current.amount
  };
  return accumulator;
}, {});
console.log(result);

Answer №2

To create the newData in parts, start by gathering all dates and fruits, such as:

const dates = [];
const fruits = [];

for (const item of data) {
  if (!dates.includes(data.date_sold))
    dates.push(data.date_sold);
  if (!fruits.includes(data.fruit))
    fruits.push(data.push);
}

Next, construct your newDate object by following these steps:

const newData = Object.fromValues(
  dates.map(function (date) {
    const fruitsCount = Object.fromValues(
      fruits.map(function (fruit) {
        return [fruit, 0];
      })
    });
    for (const item of data) {
      if (item.date === date) {
        fruitsCount[item.fruit] += item.amout;
      }
    }
    return [data, fruitsCount];
);

Answer №3

I find the following code snippet to be more easily understood.

const salesByDate = {};

salesData.forEach(sale => {
    const dates = Object.keys(salesByDate);
    if (dates.indexOf(sale.date) > -1) {
        const amountSold = salesByDate[sale.date][sale.product];
        salesByDate[sale.date][sale.product] = (amountSold || 0) + sale.quantity;
    } else {
        salesByDate[sale.date] = {
            [sale.product]: sale.quantity
        };
    }
});

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

Highchart: precise positioning of ticks on axis

Is there a way to precisely determine the distance or establish an exact distance (in pixels) between two ticks on the x-axis using Highchart? I attempted to use tickPixelInterval, but it doesn't appear to accurately set the distance between two tick ...

How can I retrieve a formController in AngularJS?

When trying to reset the data in a form and calling form.setPristine(), I encounter an issue where the formController is not registered within the $scope. It may sound like a basic question, but how can I locate the formController? Within the code snippe ...

The next.js application utilizing a custom server is experiencing rendering issues

Expanding my knowledge to next.js, I might be overlooking a simple aspect. My goal is to implement custom routes, so I crafted a server.js file and adjusted the command in my package.json to node server.js. Below is the entirety of the server.js file: con ...

Utilizing a callback to modify a local variable in JavaScript

Below is my jQuery code: function checkHotelExists(value, col) { var url = base_url + 'ajax/checkuniquehotel'; var response = false; $.get(url, {hotelname:value}, function(data){ if (data === 'true&apos ...

Is it possible to combine Sprites as Geometries in Three.js?

My dilemma involves placing labels with the names of cities on a terrain. However, once the number of labels exceeds ten, the frames per second drastically decrease. I've tried implementing the code provided at My code looks something like this: va ...

Utilize Jquery to insert the text into the input or textarea field

<div class="ctrlHolder"> <label for="" id="name.label">Name</label> <input name="name" id="name" type="text" class="textInput small" /> <p class="formHint">Please enter the name of the item you are submitting</p> </di ...

Avoiding overlapping handlers in VueJS

There seems to be an issue where a function is being called from mounted(), but when the elements are loaded, the same function is also called again, interrupting the first call and preventing it from completing the entire process. <b-table id=&qu ...

Declaring types globally in Visual Studio Code for JavaScript programming

My /typings/$app.d.ts file has the following structure: declare class App { test: object } export const $app: App; https://i.sstatic.net/3HW7M.png In order to enable intellisense, I have to auto-import it, resulting in a line like this at the begin ...

What is the most streamlined method for identifying if a browser is operating on an Android device?

Looking to add a banner on our mobile website specifically for Android users to prompt them to download the Android mobile app. Wanting to find a lightweight way to detect in Javascript if the user is using an Android browser. Have reviewed various soluti ...

Custom validation preventing Ng-minlength from functioning correctly

I'm currently working on an angularJS project where I am trying to create a form for users to input their username. The application needs to validate if the username is available in the database and if it falls within a character length of 5 to 10. & ...

The information entered into dynamically generated text fields is not being successfully passed to the request()->validate() array

My form allows users to input their educational background from Elementary school to College. If they wish to include any additional studies, they can click the "Add Other Studies" button, which will then reveal a new set of input fields specifically for o ...

"Encountered an undefined error with the title property of this.state.project in the Wordpress API

I'm currently working on a project that involves a Backend Wordpress and a front-end React setup. However, I've encountered an issue when attempting to retrieve the title.rendered from the JSON Data. This error is displayed: TypeError: this.sta ...

Tips for accessing a variable located in a different directory

I'm facing some confusion regarding creating a global variable that can be accessed in another file. Currently, I have a chat and login folder setup. Within the login folder, there are three possible users to choose from. When a user clicks on one of ...

HTML5 coding can be enhanced by applying unique CSS rules for alignment purposes

html { font-family: "Open Sans", sans-serif; font-weight: 100; background-color: #fbfbfb; } body { font-family: "Open Sans", sans-serif; font-weight: 100; } body h1 { font-weight: 100; } body h3 { font-family: "Open Sans", sans-serif; fo ...

Display the invoice bill using text in a Vue component

Hello, I am looking to print an invoice that resembles the one shown in this picture https://i.sstatic.net/6mzwe.jpg However, when I try to print it, I get a different output with some additional elements https://i.sstatic.net/uaKZC.jpg I am using vue. ...

Is there a way to implement a @click event on a Vuetify expansion panel?

Whenever I use <a>, the design of the <v-btn> expansion panel breaks. How can I incorporate the click event in this situation? I attempted to utilize filters, watch, and computed, but it didn't work. Here's my code: <v-card xs1 ...

Hello there, could you please point out where the error is located in this code?

$(document).ready(function(){ $('#nav-b .navbar-item li a').click(function(){ $('#nav-b .navbar-item li a').removeClass('active'); $(this).addClass('active'); }); }); < ...

SMTPConnection._formatError experienced a connection timeout in Nodemailer

Our email server configuration using Nodemailer SMTP settings looked like this: host: example.host port: 25 pool: true maxConnections: 2 authMethod: 'PLAIN' auth: user: 'username' pass: 'pass' We encou ...

Steps for revealing a section of a webpage by completing an HTML form

Looking for a way to validate and store data from an HTML form in order to reveal a specific section of my webpage. Here's the scenario: I run an online shop and want to capture leads. On my landing page, I want to only show the purchase button and p ...

Issue with displaying full screen Google map within a large modal in Bootstrap 4

I successfully integrated a Google map into a large modal using Bootstrap 4. However, I encountered an issue where the map would not display when clicking the fullscreen button within the modal. I am struggling to find a solution for this problem. How can ...