Reformat a JSON file and save as a new file

I have a lengthy list of one-level JSON data similar to the example below: json-old.json

[
{"stock": "abc", "volume": "45434", "price": "31", "date": "10/12/12"},
{"stock": "abc", "volume": "45435", "price": "30", "date": "10/13/12"},
{"stock": "xyz", "volume": "34465", "price": "14", "date": "10/12/12"},
{"stock": "xyz", "volume": "34434", "price": "14", "date": "10/13/12"},
{"stock": "zzz", "volume": "76755", "price": "65", "date": "10/12/12"},
{"stock": "zzz", "volume": "85646", "price": "67", "date": "10/13/12"}
]

I am looking for a way to transform this file into a new format in another file: json-new.json

[
{ 
   "abc": {
      "10/12/12": { "volume": "45434", "price": "31" },
      "10/13/12": { "volume": "45435", "price": "30" }
   }
},
{
   "xyz": {
      "10/12/12": { "volume": "34465", "price": "14" },
      "10/13/12": { "volume": "34434", "price": "14" }
   }
},
{
   "zzz": {
      "10/12/12": { "volume": "76755", "price": "65" },
      "10/13/12": { "volume": "85646", "price": "67" }
   }
}
]

Essentially, I want to restructure and nest the data based on the 'stock' and 'date' properties.

Are there any libraries available in JavaScript or Node.js that can assist with automating this conversion process? I have numerous files in a folder that need to be transformed into a single file with the desired structure (to facilitate uploading to a database like Firebase).

Answer №1

One helpful method to consider is Array.reduce

const data = [
    { "stock": "abc", "volume": "45434", "price": "31", "date": "10/12/12" },
    { "stock": "abc", "volume": "45435", "price": "30", "date": "10/13/12" },
    { "stock": "xyz", "volume": "34465", "price": "14", "date": "10/12/12" },
    { "stock": "xyz", "volume": "34434", "price": "14", "date": "10/13/12" },
    { "stock": "zzz", "volume": "76755", "price": "65", "date": "10/12/12" },
    { "stock": "zzz", "volume": "85646", "price": "67", "date": "10/13/12" }
]

const formattedData = data.reduce((result, current) => {
    const {stock, date, ...rest} = current

    const info = result[stock] || {}
    info[date] = rest
    result[stock] = info

    return result
}, {})

console.log([formattedData])

Answer №2

To implement a for loop, you can follow the example below:

var data = [
        { "name": "apple", "quantity": "100", "price": "$1", "date": "12/01/2021" },
        { "name": "banana", "quantity": "50", "price": "$0.50", "date": "12/02/2021" },
        { "name": "orange", "quantity": "75", "price": "$0.75", "date": "12/01/2021" }
    ];
    var output = [];
    var results = []
    for (var item in data)
    {
        var fruit=data[item];
        var info = {
            'quantity': fruit.quantity,
            'price': fruit.price
        }
        var inventory = output[fruit.name] || {};
        inventory[fruit.date] = info;
        output[fruit.name] = inventory;
    }
    for (i in output) {
        var newObj = {}
        newObj[i] = output[i];
        results.push(newObj)
    }
    console.log(results);
   // console.log(JSON.stringify(results));

You can now use the JSON format as your new data structure.

Answer №3

This piece of code should get the job done:

const fs = require('fs')

const groupBy = (items, key) => items.reduce(
    (result, item) => ({
      ...result,
      [item[key]]: [
        ...(result[item[key]] || []),
        item,
      ],
    }), 
    {},
);

const inputFileName = process.argv[2]
const outputFileName = process.argv[3]

const jsonData = JSON.parse(fs.readFileSync(inputFileName, 'utf8'));
const groupedStock = groupBy(jsonData,'stock')
const groupedDate = {}
for(stock in groupedStock)
    groupedDate[stock] = groupBy(groupedStock[stock],'date')

const filteredData = {}
for(stock in groupedDate){
    filteredData[stock] = {}
    for (date in groupedDate[stock]) {
        filteredData[stock][date] = {
            price: groupedDate[stock][date][0].price,
            volume: groupedDate[stock][date][0].volume
        }
    }
}

const result = []
for(stock in filteredData)
    result.push({
        [stock]: filteredData[stock]
    })


fs.writeFileSync(outputFileName, JSON.stringify(result,null,2));

To run this program, use

node convert.js json-old.json json-new.json

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

Error: Order placement failed due to a validation error

I've been working on developing an ecommerce application, and while the frontend is complete, I've encountered a problem when placing an order. After going through all my files, I couldn't pinpoint where the issue was originating from. Despi ...

What is the process for converting variables from browser script to Python code?

I ran the script below in my browser webdriver.execute_script("document.getElementsByClassName('bulk_item').length") My goal is to have the number that the script returns stored in a variable called elem for easy access. However, simp ...

Creating an HTML element that can zoom, using dimensions specified in percentages but appearing as if they were specified in pixels

This question may seem simple, but I have been searching for an answer and haven't found one yet. Imagine we have an HTML element with dimensions specified in pixels: <div style="width:750px; height: 250px"></div> We can easily resize i ...

Is it possible to configure Nginx to provide HTTPS on port 10000 and implement Basic Auth for an Express app?

My Linux NodeJS/Express application is designed to serve a text file located at http://example.com/secret.txt. I am looking to restrict access to this file only over HTTPS on port 10000 with Basic Auth security measures in place. It's important to no ...

The then() function in Node.js is triggered before the promise is fully resolved

I'm struggling to get my Promise function working as intended. Here's what I need to accomplish: I am receiving file names from stdout, splitting them into lines, and then copying them. Once the copy operation is complete, I want to initiate oth ...

Can someone assist me in populating my dropdown menu with the data from my JSON response?

I have received JSON data from a C# web method in the following format: {"d":["ADAMS CITY","BOULDER","ANTON","ARBOLES"]} There is an ASP.NET dropdown with the ID #city. After receiving a success alert on my AJAX request, how can I display this data in th ...

Having trouble with the error message "yo: command not found" after installing Yeoman? Here's how you can troub

After following all the steps provided, I attempted to install yeoman twice using npm: Despite uninstalling node as per these instructions after the initial failure: How do I completely uninstall Node.js, and reinstall from beginning (Mac OS X), I encoun ...

How can I dynamically adjust an element's attribute as a user scrolls past it (creating a sticky effect)?

For instance, when you visit and try scrolling up, you will notice a bar displaying: "Typography Code Tables Forms Buttons Icons by Glyphicons" As you continue to scroll past the element, a class is added to alter the appearance. However, as you scrol ...

When props are passed through the root element, the data becomes inaccessible

I am currently using React in conjunction with an EJS template. I am attempting to pass data from an API to React, but I am facing difficulties in finding a way to accomplish this. Here is the API code snippet: module.exports.home_get = async (req,res) =&g ...

Exploring the (*ngFor) Directive to Iterate Through an [object Object]

Attempting to iterate through the array using *ngFor as shown below. let geographicalArea = [{ "_id": "5e77f43e48348935b4571fa7", "name": "Latin America", "employee": { "_id": "5e77c50c4476e734d8b30dc6", "name": "Thomas", ...

Tips for preventing breaks in typography

I have implemented a material ui Typography component, but it's causing a line break even though there is enough space. Here is the code snippet: <Box flexDirection="row"> <Typography> Gender: <RadioGroup row ...

Issue with Remote Form in Rails: Encountering Syntax Error Due to Unexpected Token

I am trying to update a form: <%= form_for([@group, lesson], remote: true) do |f| %> <tr id='<%= lesson.id%>' > <td><%= f.text_field :time %></td> <td><%= f ...

A guide on implementing Expected conditions in Selenium using Node.js

Can you please provide guidance on importing the Expected Condition class in selenium with node js? ...

Incorporating Bootstrap JS into Next.js

Currently, I am in the process of learning next.js and experimenting with incorporating Bootstrap into my projects. To begin, I initiated a new project using npx create-next-app@latest my-app, utilizing the newly created "app" directory structure. Follow ...

unable to exit a function in node.js

I am facing an issue with three blocks of code where the first block executes initially, passes its result to the second block, and then finally sends the final result to the third block which is supposed to send data to the route. However, I am encounteri ...

What causes the accordion class to activate panels with varying names?

Why are some of my accordions triggering other accordions when they have different names? I've been working on resolving the issue where opening the second accordion in the second, third, or fourth panel closes the second accordion in the first panel ...

What is the rationale behind not passing $scope to a service in AngularJS, and is it considered bad practice?

Is it advisable not to pass $scope to a service for certain reasons? I understand that services are intended to be reusable singletons, and passing a (potentially) large object to the service could lead to maintenance issues. However, assuming there is so ...

How can I add content using HTML or JavaScript?

How can I append a .txt file using HTML or Java without ActiveX prompts getting in the way? It's becoming quite annoying! Is there a simple way to script this task without having to deal with ActiveX? The current script snippet looks something like ...

Transform the Material UI grid orientation to horizontal row for content display

I'm just starting out with material UI and I've put together a grid that includes two components - an autocomplete and a button. Right now, they're stacked on top of each other, but I want to align them side by side in a row. Here's the ...

Uncovering a Memory Leak in Node.js

I have a calendar loading from Google, but each time I do it, my Node.js application's memory usage increases by 2 MB. Even if I remove the module, the memory issue persists. I need to reload the calendar every 5 or 10 minutes to check for updates. G ...