Generating an array of objects using key-value pairs

After receiving a JSON object with key-value pairs from a service, my task is to dynamically create objects based on them and group them by one column.

Here is an example of the JSON structure:

[
    { "Group" : "A", "Key" : "Name", "Value" : "John" },
    { "Group" : "A", "Key" : "Age",  "Value" : "30" },
    { "Group" : "A", "Key" : "City", "Value" : "London" },
    { "Group" : "B", "Key" : "Name", "Value" : "Hans" },
    { "Group" : "B", "Key" : "Age",  "Value" : "35" },
    { "Group" : "B", "Key" : "City", "Value" : "Berlin" },
    { "Group" : "C", "Key" : "Name", "Value" : "José" },
    { "Group" : "C", "Key" : "Age",  "Value" : "25" },
    { "Group" : "C", "Key" : "City", "Value" : "Madrid" }
]

The desired output should be an array of objects like this:

[
    { Group : "A", Name : "John", Age : 30, City : "London" },
    { Group : "B", Name : "Hans", Age : 35, City : "Berlin" },
    { Group : "C", Name : "José", Age : 25, City : "Madrid" }
]

There can be any number of key-value pairs within each group.

I currently have a functional solution for this task, but I am unsure if it is the most efficient approach:

var items = [
    { "Group" : "A", "Key" : "Name", "Value" : "John" },
    { "Group" : "A", "Key" : "Age",  "Value" : "30" },
    { "Group" : "A", "Key" : "City", "Value" : "London" },
    { "Group" : "B", "Key" : "Name", "Value" : "Hans" },
    { "Group" : "B", "Key" : "Age",  "Value" : "35" },
    { "Group" : "B", "Key" : "City", "Value" : "Berlin" },
    { "Group" : "C", "Key" : "Name", "Value" : "José" },
    { "Group" : "C", "Key" : "Age",  "Value" : "25" },
    { "Group" : "C", "Key" : "City", "Value" : "Madrid" }
], item, record, hash = {}, results = [];

// Creating a "hash" object to organize data
for (var i = 0, len = items.length; i < len; i += 1) {
    item = items[i];

  if (!hash[item.Group]) {
    hash[item.Group] = {
      Group : item.Group
    };
  }
  hash[item.Group][item.Key] = item.Value;
}

// Adding each item in the hash to the results array
for (record in hash) {
  if(hash.hasOwnProperty(record)) {
    results.push(hash[record]);
  }
}

You can view a demo here: http://jsbin.com/ozizom/1/

If you have a more optimal solution for this problem, please feel free to share.

Answer №1

In the case that the JSON records are consistently sorted by Group, here is an alternative method:

var json = [
    { "Group" : "A", "Key" : "Name", "Value" : "John" },
    { "Group" : "A", "Key" : "Age",  "Value" : "30" },
    { "Group" : "A", "Key" : "City", "Value" : "London" },
    { "Group" : "B", "Key" : "Name", "Value" : "Hans" },
    { "Group" : "B", "Key" : "Age",  "Value" : "35" },
    { "Group" : "B", "Key" : "City", "Value" : "Berlin" },
    { "Group" : "C", "Key" : "Name", "Value" : "José" },
    { "Group" : "C", "Key" : "Age",  "Value" : "25" },
    { "Group" : "C", "Key" : "City", "Value" : "Madrid" }
];

var array = [];
var previousGroup = null;

for(var i=0; i<json.length; i++) {
    var group = json[i].Group;
    if(previousGroup != group) {
        array.push({Group: group});
        previousGroup = group;
    }
    array[array.length-1][json[i].Key] = json[i].Value;
}

Here is a live demonstration of this implementation.

Answer №2

Discover a clever solution in this code snippet that optimizes the code size using JavaScript idioms. Unlike other solutions, this one is not reliant on the sequence of input values:

var data = [
  {Group: 'A', Key: 'Name', Value: 'John'},
  {Group: 'A', Key: 'Age', Value: '30'},
  {Group: 'A', Key: 'City', Value: 'London'},
  {Group: 'B', Key: 'Name', Value: 'Hans'},
  {Group: 'B', Key: 'Age', Value: '35'},
  {Group: 'B', Key: 'City', Value: 'Berlin'},
  {Group: 'C', Key: 'Name', Value: 'José'},
  {Group: 'C', Key: 'Age', Value: '25'},
  {Group: 'C', Key: 'City', Value: 'Madrid'}
];

var map = {};
data.forEach(function(item) {
  map[item.Group] = map[item.Group] || {Group: item.Group};
  map[item.Group][item.Key] = item.Value;
});

var output = Object.keys(map).map(function(key) { return map[key]; });

View a live demo at http://jsfiddle.net/arQww.

Check out this highly efficient solution that considers sorted values based on Group:

var group, results = [];
for (var index = 0; index < data.length; ) {
  results.push({Group: group = data[index].Group});
  do {
    results[results.length - 1][data[index].Key] = data[index].Value;  
  } while (++index < data.length && data[index].Group == group);
}

For a comprehensive performance analysis, visit http://jsperf.com/vnmzc. Both solutions operate in O(n) time complexity, with the second option showcasing slightly better speed. However, due to negligible real-world variance, the first approach is recommended for its simplicity and versatility.

Answer №3

If you find yourself needing to manipulate data frequently, I suggest checking out the underscore framework. Below is an example of how a solution might be implemented using underscore:

/*
 We first organize items into an object structure with groups and attributes
 Next, for each group, we create a result object that represents the group,
 then merge the result object with a new object created from attribute keys and values
*/
_.map(_.groupBy(items, function (item) {return item.Group}),
     function (attributes, group) {
        return _.extend({Group: group},
                        _.object(_.pluck(attributes, 'Key'),
                                 _.pluck(attributes, 'Value')))
    })

Answer №4

Can someone assist me with a similar issue? I need help summing values from an array of objects.

var myArrWithObj = [
    {DateToSort: "Jul2014", ValueOneToSum: "60", ValueTwoToSum: "15"},
    {DateToSort: "Jul2014", ValueOneToSum: "30", ValueTwoToSum: "50"},
    {DateToSort: "Jul2014", ValueOneToSum: "12", ValueTwoToSum: "22"},
    {DateToSort: "Aug2014", ValueOneToSum: "65", ValueTwoToSum: "25"},
    {DateToSort: "Aug2014", ValueOneToSum: "13", ValueTwoToSum: "10"},
    {DateToSort: "Aug2014", ValueOneToSum: "90", ValueTwoToSum: "20"},
    {DateToSort: "Sep2014", ValueOneToSum: "60", ValueTwoToSum: "15"},
        {DateToSort: "Sep2014", ValueOneToSum: "60", ValueTwoToSum: "18"},
        {DateToSort: "Sep2014", ValueOneToSum: "75", ValueTwoToSum: "18"}
                   ];

I would like to create a select menu where the user can choose a specific month, such as August 2014, and then calculate the total sum of ValueOneToSum and ValueTwoToSum for that month. How can I achieve this?

For instance, if the user selects August 2014, the total sum of ValueOneToSum would be 168 and the total sum of ValueTwoToSum would be 55.

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

Converting JSON data into a Pandas DataFrame using Flask

I'm currently working on parsing JSON data in Flask from a POST request. So far, everything seems to be functioning properly: from flask import Flask from flask import request import io import json import pandas as pd app = Flask(__name__) @app.rou ...

using withDefaultPrettyPrinter() does not result in the output being automatically formatted

I am facing an issue while saving JSON data to a file. Below is the code I am using for serialization: private String serializeToJson(T item) { String json; ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); try { ...

Tips for sending multiple JSON objects using the ajax() method

As of now, I have successfully implemented a $.getJSON() call to fetch a JSON string from a specific URL. Here is the simplified code that is currently functioning well: $.getJSON("myURL",function(data){ var receivedJSON = data; }); The retrieved JSO ...

Increase the worth of current value

Whenever a user enters their name into an input box, I want it to be shown after the word 'hello'. However, currently, the word 'hello' gets replaced by the user's name instead of being displayed after it. var name = document.ge ...

Problem with Chrome's version causing regex malfunction

Seeking assistance with extracting a string from a URL of an image using regular expressions and the match() function in JavaScript. The code works flawlessly on Chrome version 62, but encounters issues on older versions like Chrome 58. Here are the specif ...

Transfer data to S3 directly from memory instead of saving it as a file first

I need to convert a string into a CSV format and upload it directly to my S3 bucket without writing it into a file. Is there a way to achieve this using memory streams? Instead of reading from a file, I want to create a stream with the string content itse ...

Is there a way for me to instruct Swift to hold off until the value has finished downloading?

Hey there, morning folks! I'm currently facing an issue where I want to populate a UITableView with JSON data fetched from my website's API. The challenge is that the override functions of the tableview get executed before my JSON data is downl ...

Can you please explain the purpose of this function?

I came across this code snippet on a website and I'm curious about its function and purpose. While I'm familiar with PHP, HTML, CSS, and JavaScript, I haven't had the chance to learn JQUERY and AJAX yet. Specifically, I'm interested in ...

What is the process for extracting content from CSS comments or annotations in a stylesheet?

Here's an interesting concept: allowing users to define a set of CSS rules with annotations. For example: /* @name Page style */ body { font: 16px/1.5 Arial; /* @editable */ background-color: #fff; /* @editable */ } /* @name Section header */ ...

Storybook/vue causing issues with aliases not functioning as intended

I'm currently utilizing Storybook for Vue and I am endeavoring to integrate aliases into the webpack config within storybook/main.js: resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js', '@': path.resolve ...

Grabbing an element with Cheerio in Node.JS

Struggling to extract the price element from this page: Running the console.log returns nothing, even though I'm certain I'm targeting the correct element. Any advice on how to tackle this issue? var request = require('request'); var ...

Using ExtJS and jQuery in ASP.NET development

There seems to be a debate between jQuery and ExtJS in some posts I've come across. While I haven't delved into jQuery extensively, my understanding is that it may not offer the same level of user interface capabilities as ExtJS. Can someone conf ...

A wireframe in three.js displaying shapes with invisible edges as dashed lines

I'm undertaking a project to develop a specific type of 3D object using three.js. My goal is to have a cube displayed in wireframe mode with only the edges visible. However, I would like the edges that are positioned behind the cube to appear dashed. ...

Apologies, but we cannot access the file located at '/app/backend/frontend/build/index.html' as it cannot be found in the specified directory

After pushing my MERN stack project to Heroku Master for deployment, I encountered an issue where the app was showing "Not Found" upon opening. Despite spending hours researching related Stack Overflow questions, I couldn't find a solution. I built m ...

To-do list application: organizing tasks into local storage for easy access

Struggling to make a todo-app function properly with localstorage, I'm a bit lost on the process. The app is built within a Vue.js project using a main.js file that connects two Classes: App.js and Todo.js (see below). import App from "./classes/ ...

What is the jQuery alternative for the classList property in vanilla JavaScript?

Currently, I am working on a collaborative project with two acquaintances. One of the requirements is to stick to either vanilla JavaScript selectors like document.getElementById("thisDiv"); or jQuery selectors such as $("#thisDiv"); to maintain consis ...

Ways to send JSON data to a FastAPI backend without relying on Swagger UI

Trying to perform a basic POST operation with FastAPI. A simple structure has been set up using BaseModel, consisting of only two attributes, name and roll. import uvicorn from fastapi import FastAPI from pydantic import BaseModel class Item(BaseModel): ...

The first three AJAX requests are successful, but the fourth one fails to reach the PHP script

I am currently working on cascaded selects (a total of 4) that retrieve data from a database. To populate them, I use SQL queries based on the selection made in the previous select element. To establish communication between the select element and the subs ...

Managing link clicks using jQuery

I have a question that seems simple, but I am struggling to find the correct solution. In my phonegap app, I have a login feature where I check the results using ajax after the user clicks: <a href="home.html" data-transition="pop">GO</a> The ...

What is the process for obtaining the number of video views using the YouTube API?

I have a straightforward question: How can I retrieve the number of video views using the YouTube API? Although the task is simple, I need to perform this query on a large number of videos frequently. Is there a way to access their YouTube API in order to ...