为了账号安全,请及时绑定邮箱和手机立即绑定

合并具有相似键值的对象数组并创建包含较少对象的新数组

合并具有相似键值的对象数组并创建包含较少对象的新数组

拉莫斯之舞 2023-08-24 10:21:29
我有一个对象数组(超过 5000 个条目),其中包含Units Sold来自多个国家/地区的数据。我试图获取所有类似的国家/地区,添加金额,然后返回一个新的对象数组,其中每个国家/地区及其总金额仅出现一次。我认为下面的代码是正确的,但我确信我正在采取低效的路线,并且肯定它是完全错误的。我确定我需要应用该reduce()方法,并且可能还需要使用其他方法forEach(),但我不确定如何使用。已经这样做了几天了,并且希望/感谢一些帮助。谢谢!  const data = [     {      "Country" : "USA",      "Units Sold" : 1245.56     },     {      "Country" : "Spain",      "Units Sold" : 7843.50     },     {      "Country" : "USA",      "Units Sold" : 1435.99     },     {      "Country" : "Uruguay",      "Units Sold" : 594.20     },    ]    let result = [];    data.forEach((block) => {      if (result.length === 0) {        result.push({          Country: block.Country,          "Units Sold": block["Units Sold"],        });      } else {        data.forEach((e) => {          if (e.Country === block.Country) {            console.log("add values");            e["Units Sold"] += block["Units Sold"];            console.log(e);          }        });      }    });期望的结果:    const newArray = [     {      "Country" : "USA",      "Units Sold" : 2681.55     },     {      "Country" : "Spain",      "Units Sold" : 7843.50     },     {      "Country" : "Uruguay",      "Units Sold" : 594.20     },    ]
查看完整描述

2 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

有时,与其试图在一次操作中完成所有事情,不如一步一步地做事情更有意义。例如,您的问题可以分为两个步骤。

  1. 按国家分组

  2. 离散组求和

现在我们所要做的就是创建一些构建块来帮助您实现这一结果。

通过...分组

按运算符分组很简单,您已经在这样做了。但我们可以通过使用地图使其更快一些。这使我们能够立即判断一个国家/地区组是否存在,而无需搜索我们的数组。

const groupBy = (array, selector) => {

  return array.reduce((groups, value) => {

    const key = selector(value);

    const group = groups.get(key);

    

    if (group == null) {

        groups.set(key, [value]);

    } else {

        group.push(value);

    }

    

    return groups;

  }, new Map());

};


const groups = groupBy(data, (d) => d["Country"]);

我们在这里使用array.reducereduce将集合转换为单个值。

接下来,我们将使用求和运算符来遍历每个组并对选择器返回的内容求和。

const sum = (array, selector) => {

  return array.reduce((s, value) => {

    return s + selector(value);

  }, 0);

};

这看起来应该与 非常相似groupBy。我们将reducing多个值合并为一个总和。


结果

现在,既然我们有了两个构建块,我们只需将它们单击在一起即可获得我们想要的结果。


const groups = groupBy(data, (v) => v["Country"])

const unitsSoldByCountry = Array.from(groups.entries())

  .map(([country, sales]) => {

    return {

      "Country": country,

      "Units Sold": sum(sales, (s) => s["Units Sold"])

    };

  });

我们groupBy国家。然后,对于每个群体(国家),我们都会sum增加他们的销售单位。我们在这里使用array.map运算符,因为我们希望如果有N国家/地区,我们将返回N求和记录。

const data = [

  {

    "Country": "USA",

    "Units Sold": 1245.56

  },

  {

    "Country": "Spain",

    "Units Sold": 7843.50

  },

  {

    "Country": "USA",

    "Units Sold": 1435.99

  },

  {

    "Country": "Uruguay",

    "Units Sold": 594.20

  }

];


const groupBy = (array, selector) => {

  return array.reduce((groups, value) => {

    const key = selector(value);

    const group = groups.get(key);

    

    if (group == null) {

        groups.set(key, [value]);

    } else {

        group.push(value);

    }

    

    return groups;

  }, new Map());

};


const sum = (array, selector) => {

  return array.reduce((s, value) => {

    return s + selector(value);

  }, 0);

};


const groups = groupBy(data, (v) => v['Country'])

const unitsSoldByCountry = Array.from(groups.entries())

  .map(([country, sales]) => {

    return {

      "Country": country,

      "Units Sold": sum(sales, (s) => s["Units Sold"])

    };

  });


console.log(unitsSoldByCountry);


肯定有一些方法可以用更少的代码行来做到这一点。但我更喜欢可重用的组件,它们允许更多的声明性编程,使您的代码更易于阅读和更改。



查看完整回答
反对 回复 2023-08-24
?
慕沐林林

TA贡献2016条经验 获得超9个赞

const data = [

        {

  "Country" : "USA",

  "sold" : 15.56

 },

 {

  "Country" : "USA",

  "sold" : 1245.56

 },

 {

  "Country" : "Spain",

  "sold" : 7843.50

 },

 {

  "Country" : "USA",

  "sold" : 1435.99

 },

 {

  "Country" : "Uruguay",

  "sold" : 594.20

 },

]


const usaEntries= data.filter(item => item.Country === 'USA')

const sum = pays.reduce((a, n) => (a + Number(n.sold)), 0);

第一行检索所有美国条目,第二行对所有商品的销售总额进行求和,它有两个参数,a 表示累加器,n 表示当前值,0 是将累加器初始化为零。


您也可以在一行中完成


 const sum = data.filter(item => item.Country === 'USA').reduce((a, n) => (a + Number(n.sold)), 0);

您还可以将所有国家/地区分组到一个数组中


    let group = data.reduce((a, n) => {


        a[n.Country] = [...a[n.Country] || [], n];

        return a;

    }, {});

然后,您可以使用reduce对每个项目应用求和函数,以获得每个国家/地区的销售情况。


查看完整回答
反对 回复 2023-08-24
  • 2 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信