Murlidhar Fichadia Murlidhar Fichadia - 1 month ago 14
Javascript Question

Sum all the values in an object by filtering country attribute - javascript

I have dataset1.grants which has objects in a form

As you can notice below that the main object is called grants which has an important field called Value and an object nested inside grants called "organisation" which has an important Country field.

dataset1.grants object example

I would like to calculate sum of all the Values by Country. And there are 500+ objects and 5+ countries. I want to create an array object which will have {country:"england", Total_value: 23455623} something like this:

How do I keep on comparing CountryList array that I have with nested object called Organisation.Country and add++ value to the total for a country.

Code So Far:

var countries = {};

dataset1.organisations.forEach(function(org)
{
countries[org.Country]=true //gets all the countries from dataset and sets it to true in countries object
})
var countryList = []; //has list of countries in array
for (var key in countries)
{
countryList.push(key);
}


Object

{
"grant": 0,
"ID": "EP/E027261/1",
"Title": "Semiconductor Research at the Materials-Device Interface",
"PIID": "6674",
"Scheme": "Platform Grants",
"StartDate": "01/05/2007",
"EndDate": "31/10/2012",
"Value": "800579",
"ResearchArea": "Non CMOS Device Technology",
"Theme": "Information and Communication Technologies",
"Department": "Electrical and Electronic Engineering",
"OrgID": "93",
"Investigators": [
{
"ID": "6674",
"Role": "Principal Investigator"
},
{
"ID": "29195",
"Role": "Co Investigator"
},
{
"ID": "90639",
"Role": "Co Investigator"
},
{
"ID": "101342",
"Role": "Co Investigator"
},
{
"ID": "12223",
"Role": "Co Investigator"
},
{
"ID": "45348",
"Role": "Co Investigator"
},
{
"ID": "96538",
"Role": "Co Investigator"
},
{
"ID": "10965",
"Role": "Co Investigator"
}
],
"Collaborators": [],
"Summary": "This proposal concerns research into electronic materials, and the development of experimental methods designed to improve our measurement capability on the nm scale. Semiconductor materials and devices are central to manufacturing, healthcare, security, administration and leisure. This pivotal position in our lives has developed gradually but is due in the main to dramatic changes that have occurred quite recently. Over the last decade semiconductor technology has begun to experience a revolution in terms of functionality based on decreased size and increased complexity, and this trend will define the future for the entire manufacturing sector. This presents immense challenges to both researchers and to manufacturers of semiconductors because the key issues are no longer the properties of bulk materials or even two-dimensional structures but the properties of small heterogeneous clusters of atoms (semiconductor, dielectric and metal) that constitute today's functional device. To put this into context, the next generation silicon NMOS transistor (45nm node) is only half the size of an influenza virus and for most applications will work in conjunction with tens of millions of similar devices. For research, development and control in manufacture the electronic and physical properties of small atomic clusters need to be probed and interactions with structures in close proximity understood.As materials and device sub-structures become more complex the experimental task of obtaining precise information becomes ever more challenging. In particular the atomic organisation and local chemistry can have a profound effect on electronic behaviour and there is a growing need to develop measurement methods which can both image structures and link shape with local spectroscopic information. In our work we are pushing forward such methods by combining x-ray spectroscopy with scanning probe imaging, using both national and international synchrotron radiation sources. In a complementary approach, we are extending electron energy loss techniques in scanning transmission electron microscopy to link chemical and structural information. Optical spectroscopy is an invaluable tool for characterising condensed matter and we are developing free electron laser pumped Raman spectroscopy in order to directly probe electron states in ultra small semiconductors.Almost all emerging device technologies are limited by these materials issues and much of our work is guided by measuring and understanding these. For example, ultra high speed, low noise detectors and amplifiers are desperately needed by radio-astronomers for the next generation of telescopes. Such devices demand near perfect material and interface properties and form part of our programme. Similarly future THz emitters are hugely challenging in terms of materials physics. One of the key developments in electronic materials in the last decade is the ability to synthesise quantum dots which give three dimensional control over quantum size effects and hold the promise of highly tuneable materials. Measuring the collective electrical properties has proved a major task and the information required to build many devices is missing. We are extending and adapting point defect measurement methods to close this gap. The increasing complexity of materials raises many issues for the device and circuit designer. An important feature of our proposed work is that we aim to include device design concepts at the materials level, and will use this work to guide our experimental programme.",
"organisation": {
"organisation": 93,
"OrgID": "93",
"Name": "The University of Manchester",
"City": "Manchester",
"Region": "Greater Manchester",
"Country": "England",
"Postcode": "M13 9PL",
"Latitude": "53.4668498",
"Longitude": "-2.2338837"
}
}

Answer

You could use this ES6 script, which uses a Map for aggregating the values keyed by country, and then converts that result with Array.from to the array of objects you require:

var result = Array.from(
    dataset1.grants.reduce( (countries, grant) =>
        countries.set(grant.organisation.Country, 
                      (countries.get(grant.organisation.Country) || 0) + +grant.Value), 
        new Map() ),
    ([country, sum]) => ({ country, sum })
);

Snippet with simplified sample data:

var dataset1 = {
    "grants": [{
        "Value": "800579",
        "organisation": {
            "Country": "England"
        }
    },{
        "Value": "100",
        "organisation": {
            "Country": "England"
        }
    },{
        "Value": "200",
        "organisation": {
            "Country": "England"
        }
    },{
        "Value": "1",
        "organisation": {
            "Country": "Belgium"
        }
    }]
};

var result = Array.from(
    dataset1.grants.reduce( (countries, grant) =>
        countries.set(grant.organisation.Country, 
            (countries.get(grant.organisation.Country) || 0) + +grant.Value), 
        new Map() ),
    ([country, sum]) => ({ country, sum })
);

console.log(result);

Comments