Utilize JSON to create a dictionary populated with objects following a complex grouping operation

I am faced with a JSON query that contains the Date, Value, Country, and Number fields. My goal is to create two separate JSON dictionaries based on unique dates (there will be two of them). The desired output can be seen in the code snippet below along with my attempts.

var json_data = {"headers":["Time","Value","Country","Number"],"rows":[["2018-09-01","#value1","United Kingdom",25],
["2018-10-01","#value1","United Kingdom",15],
["2018-09-01","#value2","United Kingdom",10],
["2018-10-01","#value2","United Kingdom",65],
["2018-09-01","#value3","United Kingdom",60],
["2018-10-01","#value3","United Kingdom",40],
["2018-09-01","#value1","Germany",55],
["2018-10-01","#value1","Germany",85],
["2018-09-01","#value2","Germany",90],
["2018-10-01","#value2","Germany",30],
["2018-09-01","#value3","Germany",20],
["2018-10-01","#value3","Germany",25],
["2018-09-01","#value1","France",55],
["2018-10-01","#value1","France",40],
["2018-09-01","#value2","France",90],
["2018-10-01","#value2","France",75],
["2018-09-01","#value3","France",30],
["2018-10-01","#value3","France",80]]};

var dataRows = json_data.rows;

var dateFields = ["2018-10-01", "2018-09-01"];

var dateMap = {};
dataRows.forEach(function(d) {
    var date = d[0];
    dateMap[date] = [];

    dateFields.forEach(function(field) {
      var object = {"data":[{"yValue": d[1], "xValue": +d[3]}]};
      dateMap[date].push( object );
    });  
});

document.getElementById("yellow").innerHTML =JSON.stringify(dateMap["2018-09-01"]);

///Target data example
var target = [{
    data: [{
      yValue: '#value1',
      xValue: 25
    }, {
      yValue: '#value2',
      xValue: 10
    }, {
      yValue: '#value3',
      xValue: 60
    }],
    name: 'United Kingdom'
    }, {
    data: [{
      yValue: '#value1',
      xValue: 55
    }, {
      yValue: '#value2',
      xValue: 90
    }, {
      yValue: '#value3',
      xValue: 20
    }],
    name: 'France'
  },{
    data: [{
      yValue: '#value1',
      xValue: 55
    }, {
      yValue: '#value2',
      xValue: 90
    }, {
      yValue: '#value3',
      xValue: 20
    }],
    name: 'Germany'
  }   
]; 

document.getElementById("purple").innerHTML =JSON.stringify(target);

///A group by attempt
//Create dictionary function (transformed JSON)
createDict = (data) => {
  let groups = data.reduce((acc, arr) => {
    if (acc.hasOwnProperty(arr[1])) {
      acc[arr[1]].push(arr);
    } else {
      acc[arr[1]] = [arr];
    }
    return acc;
  }, {});

  let results = [];
  let final = [];
  for (let g in groups) {
    let obj = {yValue: g};
    let a = groups[g][0];
    let b = groups[g][1];
    let c = groups[g][2];
      obj.xValue = a[3];
    results.push(obj);
  }
  
  final.push(results,"name");
  return results;
}

var grouped = createDict(dataRows);
document.getElementById("red").innerHTML =JSON.stringify(grouped);
<h4>Data of first branch (First date)</h4>
<div style="background:yellow;" id="yellow"></div>
<h4>Target Data (How I want it to look like)</h4>
<div style="background:green; color:white" id="purple"></div>
<h4>A group by attempt</h4>
<div style="background:red; color:white" id="red"></div>

Answer №1

To effectively sort through the data, start by filtering based on date and then grouping by country.

var info = { categories: ["Time", "Value", "Country", "Number"], details: [["2018-09-01", "#value1", "United Kingdom", 25], ["2018-10-01", "#value1", "United Kingdom", 15], ["2018-09-01", "#value2", "United Kingdom", 10], ["2018-10-01", "#value2", "United Kingdom", 65], ["2018-09-01", "#value3", "United Kingdom", 60], ["2018-10-01", "#value3", "United Kingdom", 40], ["2018-09-01", "#value1", "Germany", 55], ["2018-10-01", "#value1", "Germany", 85...
    </div>
    </div>
</p>
    </div></answer1>
<exanswer1><div class="answer accepted" i="52934197" l="4.0" c="1540216383" m="1540228193" v="1" a="TmluYSBTY2hvbHo=" ai="1447675">
<p>You can simplify the process by initially sorting the data by date and then categorizing it according to country.</p>

<p><div>
<div>
<pre class="lang-js"><code>var data = { headers: ["Time", "Value", "Country", "Number"], rows: [["2018-09-01", "#value1", "United Kingdom", 25], ["2018-10-01", "#value1", "United Kingdom", 15], ["2018-09-01", "#value2", "United Kingdom", 10], ["2018-10-01", "#value2", "United Kingdom", 65], ["2018-09-01", "#value3", "United Kingdom", 60], ["2018-10-01", "#value3", "United Kingdom", 40], ["2018-09-01", "#value1", "Germany", 55], ["2018-10-01", "#value1", "Germany", 85], ["2018-09-01", "#value2", "Germany", 90], ["2018-10-01", "#value2", "Germany", 30], ["2018-09-01", "#value3", "Germany", 20], ["2018-10-01", "#value3", "Germany", 25], ["2018-09-01", "#value1", "France", 55], ["2018-10-01", "#value1", "France", 40], ["2018-09-01", "#value2", "France", 90], ["2018-10-01", "#value2", "France", 75], ["2018-09-01", "#value3", "France", 30], ["2018-10-01", "#value3", "France", 80]] },
    dateFields = ["2018-10-01", "2018-09-01"],
    result = dateFields.map(
        date => Array
            .from(
                data.rows
                    .filter(([d]) => date === d)
                    .reduce((m, [, yValue, country, xValue]) =>
                        m.set(country, (m.get(country) || []).concat({ yValue, xValue })),
                        new Map
                    ),
                ([name, data]) => ({ data, name })
            )
    );

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

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

How can you set the Quill text editor to read-only mode in Vue after clicking a button?

I have a quill text editor that I want to customize the default setting to be readonly. When a button is clicked, this setting should toggle between true and false. Here is my component code: <template> <div ref="editor"></div> ...

Establishing a minimum date based on the date selected in the earlier datepicker

My webpage features two date pickers, one for startdate and the other for enddate. The current setup requires that the second datepicker remains inactive until a change is made to the first one. The datepicker for enddate is initially set with the startin ...

Instructions on how to insert a single parenthesis into a string using Angular or another JavaScript function

Currently, I am employing Angular JS to handle the creation of a series of SQL test scripts. A JSON file holds various test scenarios, each scenario encompassing a set of projects to be tested: $scope.tests = [ { "Date": "12/31/2017", "Project": ...

Is there a way to identify a change in the URL using JQuery?

My goal is to clear the localStorage when a user navigates to a different page. For instance, if I am currently on . When the user goes to the URL, , I want to clear the localStorage. This is my script using JQuery. $(window).unload(function(){ if ...

What could be causing npm to fail to launch?

Whenever I execute node app.js, my server functions perfectly. However, when attempting to utilize nodemon for running the server, it fails to start. The error displayed by npm start is as follows: npm ERR! code ELIFECYCLE npm ERR! errno 9009 npm ERR! < ...

Mastering the art of using res.send() in Node.js

I have been working on a project using the mongoose API with Node.js/Express. There seems to be an issue with my get request on the client side as the data is not coming through. Can someone help me figure out what's wrong? Snippet of backend app.ge ...

An issue arose when attempting to proxy to: localhost, at port 4200, for the API endpoint v1/generate

Currently, I am following a tutorial which guides me through the process of creating an application using Angular CLI, Node.js, and Express. A proxy is used to initiate the app, with the proxy configuration file looking like this: { "/api/*": { ...

Set up webpack on your Mac using npm

Seeking help to install webpack using npm: sudo npm install -g webpack The following error message is encountered: node-pre-gyp WARN Using needle for node-pre-gyp https download node-pre-gyp WARN Pre-built binaries not installable for <a href="/cdn- ...

Retrieving component layout from file

Storing the component template within inline HTML doesn't seem very sustainable to me. I prefer to load it from an external file instead. After doing some research, it appears that utilizing DOMParser() to parse the HTML file and then incorporating th ...

There seems to be a lack of definition for Angular within the angular

Currently, I am in the process of developing an Angular application. The modules I have created contain services and controllers that are all working as intended. Recently, I added angular-animate to my list of scripts, which are loaded from a cshtml file ...

AdminLTE-3 Bootstrap-4 sidebar menu with dynamic AJAX functionality fails to toggle treeview open/hide after page is fully loaded

I am looking to update the sidebar menu dynamically in the adminlte 3 dashboard with bootstrap 4 using AJAX calls. However, I have run into an issue where the menu open/close functionality is not working when the data is loaded dynamically using AJAX. On t ...

What could be the reason for the three.js scene failing to render in my Svelte application?

Scene.svelte <!-- Start by binding a container, then add the renderer to this container onMount --> <script> import { onMount } from 'svelte'; import * as THREE from 'three'; let container; onMount(async () = ...

Stay connected with AJAX's latest updates on Twitter with just 13 bytes

Twitter sends a POST request of only 13 bytes when someone follows an account. This small amount of information helps to reduce latency and server load, providing advantages for web developers. However, removing unnecessary cookies and extra information f ...

Updating button appearance when clicked using Vue.js and Tailwind CSS

As part of my learning journey, I have expanded this code to enhance my frontend skills. While I am aware that the code can be significantly shortened, I am focused on learning and broadening my experience in frontend development. The code below functions ...

Troubleshooting undefined results with AngularJS ng-repeat filter

My objective is to create a Letter Filter, where users can click on buttons from A to Z to filter the displayed data. When clicking on the letter 'A' button, only data starting with 'A' should be shown. However, I have encountered an i ...

Automatically sync textbox width with gridview dimensions

My goal is to dynamically resize a number of textboxes so that they match the width of my gridview's table headers. The gridview will always have the same number of columns, but their widths may vary. However, as shown in the image below, the width va ...

verify selection on php page using javascript

I'm having trouble with confirming the deletion of something. Despite getting an alert message when clicking the 'deleteReply' button, nothing else appears to be happening. I've tried echoing the posted variable but it's not workin ...

What steps are needed to enable the keyboard on a Otree application for mobile devices?

I previously utilized an Implicit Association Task (IAT) in an experiment conducted on computers. However, I now need to adapt this IAT for use on tablets or mobile devices. Here is how the IAT appears on a cellular device: https://i.stack.imgur.com/kNwo ...

Discover the ins and outs of the "DOM" within a string, treating it as HTML in AngularJS

Looking to extract data from a legal HTML string based on tags and attributes, but want to avoid using jQuery in favor of Angular. Are there built-in functions in Angular for this task? ...

Determine in Node.js if a word has been altered or has an additional letter compared to the previous word

I'm currently developing a feature for my Discord bot that allows users to play a word game. The objective is to input words that either change one letter from the previous word or add a letter. To implement this, I am utilizing the following function ...