Combining JSON objects to form a new object within a JSON object using JavaScript

Here is the JSON data that I have:

{"rows":[
    {"shiftId":1,"shift":"Morning","item":"Tea","value":20},
    {"shiftId":1,"shift":"Morning","item":"Coffee","value":30},
    {"shiftId":2,"shift":"Evening","item":"Tea","value":40},
    {"shiftId":2,"shift":"Evening","item":"Coffee","value":35}
]}

I want to merge entries with the same shift, add their values together, and create a new object for each item. The desired output should look like this:

{"rows":[
    {
     "shiftId":1,
     "shift":"Morning",
     "item":[{"itemName":"Tea"},{"itemName":"Coffee"}],
     "value":50
     },
    {
    "shiftId":2,
    "shift":"Evening",
    "item":[{"itemName":"Tea"},{"itemName":"Coffee"}],
    "value":75
    }
]}

I attempted to achieve this using the following code:

var merged = {rows: []};
data.forEach(function (source) {
    if (!merged.rows.some(function (row) {
        return row.shiftId == source.shiftId;
    })) {
        merged.rows.push({
            shiftId: source.shift,
            shift: source.shift,
            item: [{
                itemName: source.shift
            }],
            value: source.value
        });
    } else {
        var existRow = merged.rows.filter(function (existRow) {
            return existRow.shiftId == source.shiftId
        })[0];
        existRow.total += source.total;  // There was an error here, it should be "existRow.value += source.value"
        existRow.item = source.item.push(existRow.item);  
    }
});

However, this code is not functioning as expected. Thank you in advance for your help.

Answer №1

A possible approach is to utilize a hash table to reference objects with the same shiftId, allowing for the creation of a new array containing the collected and grouped data.

var data = { rows: [{ shiftId: 1, shift: "Morning", item: "Tea", value: 20 }, { shiftId: 1, shift: "Morning", item: "Coffee", value: 30 }, { shiftId: 2, shift: "Evening", item: "Tea", value: 40 }, { shiftId: 2, shift: "Evening", item: "Coffee", value: 35 }] },
    result = {
        rows: data.rows.reduce(function (hash) {
            return function (r, a) {
                if (!hash[a.shiftId]) {
                    hash[a.shiftId] = { shiftId: a.shiftId, shift: a.shift, item: [], value: 0 };
                    r.push(hash[a.shiftId]);
                }
                hash[a.shiftId].item.push({ itemName: a.item });
                hash[a.shiftId].value += a.value;
                return r;
            };
        }(Object.create(null)), [])
    };

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

To optimize your process, consider implementing a hash table:

var hashTable={};
var inputData={"rows":[
{"shiftId":1,"shift":"Morning","item":"Tea","value":20},
{"shiftId":1,"shift":"Morning","item":"Coffee","value":30},
{"shiftId":2,"shift":"Evening","item":"Tea","value":40},
{"shiftId":2,"shift":"Evening","item":"Coffee","value":35}
]}.rows;

inputData.forEach(function(data){
  var element=(hashTable[data.shiftId]=hashTable[data.shiftId]||{shiftId:data.shiftId,shift:data.shift,items:[],value:0});
   element.items.push({itemName:data.itemName});
   element.value+=data.value;
});

You can then generate the result as follows:

var resultingData={rows:[]};
for(key in hashTable){
 resultingData.rows.push(hashTable[key]);
}

Answer №3

Utilizing the power of Array.prototype.reduce()

const arrayItems = [{
        "shiftId": 1,
        "shift": "Morning",
        "item": "Tea",
        "value": 20
    },
    {
        "shiftId": 1,
        "shift": "Morning",
        "item": "Coffee",
        "value": 30
    },
    {
        "shiftId": 2,
        "shift": "Evening",
        "item": "Tea",
        "value": 40
    },
    {
        "shiftId": 2,
        "shift": "Evening",
        "item": "Coffee",
        "value": 35
    }
];

const newArray = arrayItems.reduce((accumulator, currentItem, index) => {
    if (!accumulator.length) { // Initial iteration
        accumulator.push(currentItem)
        return accumulator;
    }
    if (accumulator[accumulator.length - 1].shiftId === currentItem.shiftId) { // Check if current shiftId matches last shiftId
        if (!(accumulator[accumulator.length - 1].item instanceof Array)) {
            accumulator[accumulator.length - 1].item = [{ // Convert item to an array
                "itemName": accumulator[accumulator.length - 1].item
            }]
        }
        accumulator[accumulator.length - 1].item.push({ // Add current item name to the last item array
            "itemName": currentItem.item
        });
        accumulator[accumulator.length - 1].value = accumulator[accumulator.length - 1].value + currentItem.value // Value addition
    } else { // If new shiftId
        accumulator.push(currentItem);
    }
    return accumulator;
}, []);

console.log(newArray);

Answer №4

let data = {"rows":[
    {"shiftId":1,"shift":"Morning","item":"Tea","value":20},
    {"shiftId":1,"shift":"Morning","item":"Coffee","value":30},
    {"shiftId":2,"shift":"Evening","item":"Tea","value":40},
    {"shiftId":2,"shift":"Evening","item":"Coffee","value":35}
]};
let newData = {"rows":[]};

let lastShiftId = -1;
let newKey = -1;
for(key in data.rows){
  let currentShiftId = data.rows[key].shiftId;

  let obj = {"item":data.rows[key].item};
  if(lastShiftId != currentShiftId){
    newKey++;
    data.rows[key].item = [];
    newData.rows.push(data.rows[key]);    
  }

  newData.rows[newKey].item.push(obj);

  lastShiftId = currentShiftId;
}
console.log(newData.rows);

Fiddle: https://jsfiddle.net/t74ygy9L/

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

Tips for solving issues with dependencies in React applications

After running "npm install," I encountered the following errors in the console: elena@elena-dev:~/PROYECTO FINAL CTD/grupo-12/frontend/proyecto-integrador$ npm install npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While reso ...

When altering a single scope variable in AngularJS, the effect cascades to impact other scope variables as well

After uploading my code on fiddle, I noticed that changes made to the myAppObjects variable also affect another variable. Here is the link to the code: https://jsfiddle.net/owze1rcj/ Here is the HTML part of the code: <div ng-controller="MyCtrl"&g ...

Ways to identify browser version in Angular 4 to discourage IE usage

Is there a method in Angular 4 (TypeScript) for detecting the browser type? I am currently working with Angular 4 and would like to explore options for identifying the browser type when my application is loaded. I specifically want to prevent my applicati ...

Unable to retrieve values from nested objects in component.html

Hey fellow tech enthusiasts, I'm currently dealing with a complex nested JSON object retrieved from an API. Here's a snippet of the object: profile : { title:"Mr", personalInfo:{ fullNames: "John Doe", id ...

The user is defined, but the user's user ID is not specified

It seems that the user is defined, but user.user_id is not. My framework of choice is express.js and passport.js. router.post('/requestSale', function(req,res){ console.log('session user: ' + req.session.passport.user); //logs ...

Having issues with JavaScript and MySQL data retrieval following XMLHttp update to the database

After running the newNet.php file successfully creates a new entry and assigns it an auto-incremented netID. The next step is to retrieve this newly created ID and use it in the showActivities() function to display the record. Ideally, it should work like ...

communication flow in two directions between server and client

Looking for recommendations on a javascript/nodejs solution that enables bi-directional communication between server and client. The application flow involves the client sending a discovery service to the server, which responds with a challenge. The client ...

Removing data with the click of a button

I have successfully implemented a feature where clicking the "add to my stay" button displays the name and price data. Subsequently, it automatically changes to a remove button when clicked again for another addon. If I press the remove button of the first ...

Ways to include a variable in a string when using the .open("GET", "[...]") method

Is it possible to include a variable in the URL using JavaScript and PHP interaction? requeteAjax.open("GET", "../src/App/handler.php?id="); For instance, if the event number is 13, the desired URL should be: requeteAjax.open("GET", "../src/App/handler. ...

unusual interactions between curl and the Python requests library

Initially, I contemplated deleting this question. However, upon further reflection, I have decided to keep it as a live demo showcasing the importance of paying attention to details as a developer. My objective is to extract data from a website. The reque ...

Tips for creating clickable selections with AutoComplete JQuery in ASP.NET and C#

Currently, I am working on a project that involves implementing AutoComplete functionality in a textbox using JQuery AutoComplete. I have included the following file: jquery-ui.js The goal is to make the matched text appear in bold. For example, if I typ ...

NodeJS executor fails to recognize Typescript's CommonJS Internal Modules

In the process of developing my NodeJS application, I am structuring it by creating internal modules to effectively manage my code logic. This allows me to reference these modules without specifying the full path every time. internal-module.ts export cla ...

Error encountered in AWS Lambda: JSONDecodeError - Anticipating a value at line 1, column 1

I'm currently working on a AWS Lambda function that aims to push the SQS queue output into an S3 bucket. However, I'm encountering issues as the lambda function fails to push the message. The CloudWatch log displays: JSONDecodeError: Expecting v ...

Ways to convert a list of strings into a JSONArray

I recently faced a challenging coding task where I needed to extract values from a list of strings and convert them into a JSONArray. Imagine having a group of classes and needing to store the names of students in a JSONArray format. Class A Alice Bo ...

Exploring struct arrays iteratively in Go through recursive iteration

I am looking to iterate through all the available answer options stored in a JSON file: {"questions": [ {"id": 1, "question": "What is your marital status?", "answer":[ { "text" ...

What could be the reason why both the add and remove functions are unable to work simultaneously within a JavaScript function?

Hi there! I recently started diving into JavaScript and encountered a little hiccup. I've been working on a dice game where images change randomly whenever a button is clicked. The images transition from one to another, but I wanted to add a rolling ...

Having trouble with your browser freezing up after an AJAX request finishes?

Going through a tough time trying to figure this out for the past two days, but still struggling without any clue. Here's what I've been up to: Firstly, I upload a file using AJAX and instantly start processing it on the backend. $.ajax({ t ...

Variable for Ajax success not set even though the other data was returned

UPDATE: While the main question remains unchanged, I have modified the approach to now return a getButtons() function instead of a global buttons array. I am utilizing an AJAX request to fetch data from the server in order to populate a popup box, which i ...

Grouping columns partially and transforming SQL column values into JSON format

I have a SQL table with the following data: SqlTable: --------------------------------------------------------------------- |PID | LID |Name | Value | |-------------------|-------|-------------------|----------- ...

Make the mp3 file automatically download/save as by forcing the link

My website has links to mp3 files using normal <a href="file.mp3"> tags. However, many users with Apple Quicktime installed experience the mp3 files opening instead of saving when clicking on the links. Is there a way to force the browser to save t ...