【问题标题】:Sum all the values in an object by filtering country attribute - javascript通过过滤国家属性对对象中的所有值求和 - javascript
【发布时间】:2016-10-11 19:27:01
【问题描述】:

我有 dataset1.grants,其中包含表单中的对象

正如您在下面看到的,主对象称为 grants,其中有一个称为 Value 的重要字段和一个 嵌套 的对象在 grants 中称为“组织”,其中包含重要的国家字段。

我想计算按国家/地区划分的所有值的总和。并且有 500 多个对象和 5 个以上的国家。我想创建一个数组对象,它的 {country:"england", Total_value: 23455623} 是这样的:

我如何继续比较我拥有的 CountryList 数组与名为 Organisation.Country 的嵌套对象,并将 ++ 值添加到一个国家/地区的总数中。

到目前为止的代码:

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);
}   

对象

{
    "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"
    }
}

【问题讨论】:

  • 将对象粘贴为文本,而不是图像。 console.log(JSON.stringify(obj, null, 4))
  • 根据您的要求,我已添加该对象。请帮忙,我不太了解javascript。我来自java语言背景

标签: javascript arrays object d3.js


【解决方案1】:

您可以使用这个 ES6 脚本,它使用 Map 来聚合按国家/地区键入的值,然后将带有 Array.from 的结果转换为您需要的对象数组:

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 })
);

带有简化示例数据的片段:

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);

说明

代码以new Map() 开头,它创建了一个Map object,可用于按键组织数据(很像普通对象具有键/值)。这个空 Map 是 reduce 迭代授权并为每个授权调用(箭头)函数时将累积的初始值。

此箭头函数使用两个参数:累积值,即 Map 对象(名为 countries)和当前授权对象(名为 grant)。地图的get 方法用于从该地图中检索我们已经拥有的赠款国家/地区的内容。如果没有找到,|| 0 将启动并使用 0 代替。

当前授权的值加上+ +grant.Value。第二个加号是将字符串转换为数字的单一加号,因为从您的示例看来,Value 属性具有字符串值。

使用set 方法将此总和存储回映射中,在由资助国家键入的条目中。 set 方法的返回值是整个 Map。这很好,因为reduce 回调必须返回累积值,这就是我们的 Map。然后reduce 将为下一个授权对象再次调用回调,并将我们在上一次调用中返回的内容作为第一个参数传递,因此累积的 Map 从一个迭代传递到下一个迭代。在最终调用时,此返回值将成为 reduce 方法本身的返回值。

这个现已完成的地图包含您需要的信息,即每个国家/地区的总和。但由于您不是在寻找 Map,而是在寻找对象数组,因此又执行了一个步骤:Array.from 可以将 map 转换为对数组(即具有 2 个元素的子数组)。这很接近,但还不是您所要求的。

现在,Array.from 接受一个函数作为其第二个参数,它允许您将每个元素(对)映射(翻译)到其他东西。所以在这种情况下,我们将[country, sum] 转换为对象{country, sum}。这里我们使用了几个 ES6 特性:一个是我们可以使用解构语法定义函数参数,另一个是我们可以使用 {country: country, sum: sum} 的快捷表示法。

在最后一个箭头函数中需要一些括号,以避免 JavaScript 误解括号和/或大括号。

【讨论】:

  • 我不了解代码的某些方面,因为我对 javascript 还很陌生。你能解释一下 .reduce 、 countries.set 、 ++ grant.Value 和新地图的代码吗?或它的工作。代码中真正发生了什么
  • 我添加了一个带有解释的部分。
  • 非常感谢您的解释
【解决方案2】:

这与构建直方图非常相似。我建议对使用直方图的不同方式进行谷歌搜索,这很有教育意义。

在你的情况下,这就是我完成任务的方式。

var countries = dataset1.reduce(function(countryList, currentGrant) {
  var country = currentGrant.organisation.Country;
  var value = currentGrant.Value;

  if (!countryList[country]) countryList[country] = 0;
  countryList[country] += value;
  return countryList;
}, {});

现在您有了 {country1: value1...} 格式的数据,您可以构建任何您想要的数据结构。

var countries = [];
for (country in countryList) { 
  countries.push({country: country, totalValue: countryList[country]});
}

【讨论】:

    猜你喜欢
    • 2019-05-29
    • 2015-12-06
    • 1970-01-01
    • 2017-02-10
    • 2021-09-27
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-19
    相关资源
    最近更新 更多