简体   繁体   English

对象数组按特定键对它们进行分组

[英]array of objects group them by a specific key

I have the following array我有以下数组

const arr = [{
  agrupacion: "Total país",
  valor: "81.8",
  year: 2015
}, {
  agrupacion: "Total país",
  valor: "86.4",
  year: 2016
}, {
  agrupacion: "Total país",
  valor: "67.3",
  year: 2017
}, {
  agrupacion: "Total país",
  valor: "70.8",
  year: 2018
}, {
  agrupacion: "Total país",
  valor: "67.6",
  year: 2019
}, {
  agrupacion: "Oriental",
  valor: "78.6",
  year: 2015
}, {
  agrupacion: "Oriental",
  valor: "83.1",
  year: 2016
}, {
  agrupacion: "Oriental",
  valor: "65.6",
  year: 2017
}, {
  agrupacion: "Oriental",
  valor: "68.1",
  year: 2018
}, {
  agrupacion: "Oriental",
  valor: "63.7",
  year: 2019
}, {
  agrupacion: "Occidental",
  valor: "177.3",
  year: 2015
}, {
  agrupacion: "Occidental",
  valor: "182.9",
  year: 2016
}, {
  agrupacion: "Occidental",
  valor: "114.3",
  year: 2017
}, {
  agrupacion: "Occidental",
  valor: "144.5",
  year: 2018
}, {
  agrupacion: "Occidental",
  valor: "169.9",
  year: 2019
}, {
  agrupacion: "Urbano",
  valor: "79.6",
  year: 2015
}, {
  agrupacion: "Urbano",
  valor: "92.5",
  year: 2016
}, {
  agrupacion: "Urbano",
  valor: "62.1",
  year: 2017
}, {
  agrupacion: "Urbano",
  valor: "82.2",
  year: 2018
}, {
  agrupacion: "Urbano",
  valor: "80.6",
  year: 2019
}, {
  agrupacion: "Rural",
  valor: "86.5",
  year: 2015
}, {
  agrupacion: "Rural",
  valor: "63.7",
  year: 2016
}, {
  agrupacion: "Rural",
  valor: "87.2",
  year: 2017
}, {
  agrupacion: "Rural",
  valor: "45.7",
  year: 2018
}, {
  agrupacion: "Rural",
  valor: "38.9",
  year: 2019
}];

I used this method to achieve what I wanted:我使用这种方法来实现我想要的:

const groups = new Map(arr.map(({agrupacion}) => [agrupacion, { agrupacion }]));
for (const {agrupacion, valor, year} of arr) {
    groups.get(agrupacion)["col" + year] = +valor;
}

const result = [...groups.values()];

the output is (console.log(result )):输出是(console.log(result)):

[{
  agrupacion: "Total país",
  col2015: 81.8,
  col2016: 86.4,
  col2017: 67.3,
  col2018: 70.8,
  col2019: 67.6
}, {
  agrupacion: "Oriental",
  col2015: 78.6,
  col2016: 83.1,
  col2017: 65.6,
  col2018: 68.1,
  col2019: 63.7
}, {
  agrupacion: "Occidental",
  col2015: 177.3,
  col2016: 182.9,
  col2017: 114.3,
  col2018: 144.5,
  col2019: 169.9
}, {
  agrupacion: "Urbano",
  col2015: 79.6,
  col2016: 92.5,
  col2017: 62.1,
  col2018: 82.2,
  col2019: 80.6
}, {
  agrupacion: "Rural",
  col2015: 86.5,
  col2016: 63.7,
  col2017: 87.2,
  col2018: 45.7,
  col2019: 38.9
}];

That output is the format I need however the problem comes when I add additional data with the same "agrupacion" value to my arr array, for example I add this at the end of my arr array该输出是我需要的格式,但是当我将具有相同“agrupacion”值的附加数据添加到我的 arr 数组时,问题就出现了,例如,我将它添加到我的 arr 数组的末尾

,{
  agrupacion: "Total país",
  valor: "151",
  year: 2015
}, {
  agrupacion: "Total país",
  valor: "184",
  year: 2016
}, {
  agrupacion: "Total país",
  valor: "165",
  year: 2017
}, {
  agrupacion: "Total país",
  valor: "147",
  year: 2018
}, {
  agrupacion: "Total país",
  valor: "190",
  year: 2019
}

This is what I need:这就是我需要的:

[{
  agrupacion: "Total país",
  col2015: 81.8,
  col2016: 86.4,
  col2017: 67.3,
  col2018: 70.8,
  col2019: 67.6
}, {
  agrupacion: "Oriental",
  col2015: 78.6,
  col2016: 83.1,
  col2017: 65.6,
  col2018: 68.1,
  col2019: 63.7
}, {
  agrupacion: "Occidental",
  col2015: 177.3,
  col2016: 182.9,
  col2017: 114.3,
  col2018: 144.5,
  col2019: 169.9
}, {
  agrupacion: "Urbano",
  col2015: 79.6,
  col2016: 92.5,
  col2017: 62.1,
  col2018: 82.2,
  col2019: 80.6
}, {
  agrupacion: "Rural",
  col2015: 86.5,
  col2016: 63.7,
  col2017: 87.2,
  col2018: 45.7,
  col2019: 38.9
},{
  agrupacion: "Total país",
  col2015: 151,
  col2016: 184,
  col2017: 165,
  col2018: 147,
  col2019: 190
}];

This is what I get with my attempt:这就是我尝试得到的结果:

[{
  agrupacion: "Total país",
  col2015: 151,
  col2016: 184,
  col2017: 165,
  col2018: 147,
  col2019: 190
}, {
  agrupacion: "Oriental",
  col2015: 78.6,
  col2016: 83.1,
  col2017: 65.6,
  col2018: 68.1,
  col2019: 63.7
}, {
  agrupacion: "Occidental",
  col2015: 177.3,
  col2016: 182.9,
  col2017: 114.3,
  col2018: 144.5,
  col2019: 169.9
}, {
  agrupacion: "Urbano",
  col2015: 79.6,
  col2016: 92.5,
  col2017: 62.1,
  col2018: 82.2,
  col2019: 80.6
}, {
  agrupacion: "Rural",
  col2015: 86.5,
  col2016: 63.7,
  col2017: 87.2,
  col2018: 45.7,
  col2019: 38.9
}]

Apparently it overwrites all the values from the first "Total país" rather than repeating that agrupacion with the new values that I added显然它会覆盖第一个“Total país”中的所有值,而不是用我添加的新值重复那个 agrupacion

Try this forEach function :试试这个 forEach 函数:

 let arrayBuild = []
      let results = []
      let currentAgrupacion = ''
      let element = {}
      
      arr.forEach(elem => {
        if(currentAgrupacion !== elem.agrupacion) {
          if(currentAgrupacion !== '') {
            results.push(element)
          }
          currentAgrupacion = elem.agrupacion
          element = {
            agrupacion: elem.agrupacion
          }
      element["col"+elem.year] = parseFloat(elem.valor)
    }
    else {
      element["col"+elem.year] = parseFloat(elem.valor)
    }
  })
  results.push(element)

  console.log(results)

Reduce the array into an object where the keys correspond to the agrupacion and the values correspond to an array of objects.将数组缩减为一个对象,其中键对应于agrupacion ,值对应于对象数组。 And the length of this array is decided based on how many times an year appears for a particular agrupacion .这个数组的长度是根据一个特定的agrupacion一年出现的次数来决定的。

So, the following array:因此,以下数组:

[
  { agrupacion: "Total país", valor: "81.8", year: 2015 },
  { agrupacion: "Total país", valor: "86.4", year: 2016 },
  { agrupacion: "Total país", valor: "67.3", year: 2015 },
  { agrupacion: "Oriental", valor: "78.6", year: 2015 },
]

Is reduced into the following object:简化为以下对象:

{
  "Total país": [
    { agrupacion: "Total país", col2015: 81.8, col2016: 86.4 },
    { agrupacion: "Total país", col2015: 67.3 },
  ],
  Oriental: [{ agrupacion: "Oriental", col2015: 78.6 }],
}

And finally we get the values of this object and flatten it to the desired result.最后我们得到这个对象的值并将其展平为所需的结果。

 const arr = [ { agrupacion: "Total país", valor: "81.8", year: 2015 }, { agrupacion: "Total país", valor: "86.4", year: 2016 }, { agrupacion: "Total país", valor: "67.3", year: 2017 }, { agrupacion: "Total país", valor: "70.8", year: 2018 }, { agrupacion: "Total país", valor: "67.6", year: 2019 }, { agrupacion: "Oriental", valor: "78.6", year: 2015 }, { agrupacion: "Oriental", valor: "83.1", year: 2016 }, { agrupacion: "Oriental", valor: "65.6", year: 2017 }, { agrupacion: "Oriental", valor: "68.1", year: 2018 }, { agrupacion: "Oriental", valor: "63.7", year: 2019 }, { agrupacion: "Occidental", valor: "177.3", year: 2015 }, { agrupacion: "Occidental", valor: "182.9", year: 2016 }, { agrupacion: "Occidental", valor: "114.3", year: 2017 }, { agrupacion: "Occidental", valor: "144.5", year: 2018 }, { agrupacion: "Occidental", valor: "169.9", year: 2019 }, { agrupacion: "Urbano", valor: "79.6", year: 2015 }, { agrupacion: "Urbano", valor: "92.5", year: 2016 }, { agrupacion: "Urbano", valor: "62.1", year: 2017 }, { agrupacion: "Urbano", valor: "82.2", year: 2018 }, { agrupacion: "Urbano", valor: "80.6", year: 2019 }, { agrupacion: "Rural", valor: "86.5", year: 2015 }, { agrupacion: "Rural", valor: "63.7", year: 2016 }, { agrupacion: "Rural", valor: "87.2", year: 2017 }, { agrupacion: "Rural", valor: "45.7", year: 2018 }, { agrupacion: "Rural", valor: "38.9", year: 2019 }, { agrupacion: "Total país", valor: "151", year: 2015 }, { agrupacion: "Total país", valor: "184", year: 2016 }, { agrupacion: "Total país", valor: "165", year: 2017 }, { agrupacion: "Total país", valor: "147", year: 2018 }, { agrupacion: "Total país", valor: "190", year: 2019 }, ]; const result = Object.values( arr.reduce((r, o) => { if (!r[o.agrupacion]) { r[o.agrupacion] = [{ agrupacion: o.agrupacion }]; } const item = r[o.agrupacion].find((i) => !i["col" + o.year]); if (item) { item["col" + o.year] = parseFloat(o.valor); } else { r[o.agrupacion].push({ agrupacion: o.agrupacion, ["col" + o.year]: parseFloat(o.valor), }); } return r; }, {}) ).flat(); console.log(result);

You could keep track of the last yearData (the group of data you're collecting).您可以跟踪 last yearData (您正在收集的数据组)。 If a given col<year> is already present within this object, create a new object.如果给定的col<year>已经存在于该对象中,则创建一个新对象。

const result = [];
let yearData;
for (const {agrupacion, valor, year} of arr) {
  const colYear = `col${year}`;
  if (!yearData || colYear in yearData) {
    yearData = { agrupacion };
    result.push(yearData);
  }
  yearData[colYear] = +valor;
}

 const arr = [ { agrupacion: "Total país", valor: "81.8", year: 2015 }, { agrupacion: "Total país", valor: "86.4", year: 2016 }, { agrupacion: "Total país", valor: "67.3", year: 2017 }, { agrupacion: "Total país", valor: "70.8", year: 2018 }, { agrupacion: "Total país", valor: "67.6", year: 2019 }, { agrupacion: "Oriental", valor: "78.6", year: 2015 }, { agrupacion: "Oriental", valor: "83.1", year: 2016 }, { agrupacion: "Oriental", valor: "65.6", year: 2017 }, { agrupacion: "Oriental", valor: "68.1", year: 2018 }, { agrupacion: "Oriental", valor: "63.7", year: 2019 }, { agrupacion: "Occidental", valor: "177.3", year: 2015 }, { agrupacion: "Occidental", valor: "182.9", year: 2016 }, { agrupacion: "Occidental", valor: "114.3", year: 2017 }, { agrupacion: "Occidental", valor: "144.5", year: 2018 }, { agrupacion: "Occidental", valor: "169.9", year: 2019 }, { agrupacion: "Urbano", valor: "79.6", year: 2015 }, { agrupacion: "Urbano", valor: "92.5", year: 2016 }, { agrupacion: "Urbano", valor: "62.1", year: 2017 }, { agrupacion: "Urbano", valor: "82.2", year: 2018 }, { agrupacion: "Urbano", valor: "80.6", year: 2019 }, { agrupacion: "Rural", valor: "86.5", year: 2015 }, { agrupacion: "Rural", valor: "63.7", year: 2016 }, { agrupacion: "Rural", valor: "87.2", year: 2017 }, { agrupacion: "Rural", valor: "45.7", year: 2018 }, { agrupacion: "Rural", valor: "38.9", year: 2019 }, { agrupacion: "Total país", valor: "151", year: 2015 }, { agrupacion: "Total país", valor: "184", year: 2016 }, { agrupacion: "Total país", valor: "165", year: 2017 }, { agrupacion: "Total país", valor: "147", year: 2018 }, { agrupacion: "Total país", valor: "190", year: 2019 }, ]; const result = []; let yearData; for (const { agrupacion, valor, year } of arr) { const colYear = `col${year}`; if (!yearData || colYear in yearData) { yearData = { agrupacion }; result.push(yearData); } yearData[colYear] = +valor; } console.log(result);

The answer does assume a certain consistency in arr .答案确实假设arr具有一定的一致性。 Namely that each group of items share the exact same year range (2015-2019 in your data), and there are no missing years.即每组项目共享完全相同的年份范围(您的数据中为 2015-2019 年),并且没有缺失年份。

An example of an inconsistent input that produces a wrong output is:产生错误输出的不一致输入的示例是:

const arr = [
  { agrupacion: "a", valor: "1", year: 2015 },
  { agrupacion: "a", valor: "2", year: 2016 },
  { agrupacion: "a", valor: "3", year: 2017 },
  { agrupacion: "b", valor: "4", year: 2015 },
  // 2016 missing
  { agrupacion: "b", valor: "5", year: 2017 },
  // 2015 missing
  { agrupacion: "c", valor: "6", year: 2016 },
  { agrupacion: "c", valor: "7", year: 2017 },
];

Which results in:结果是:

[
  { agrupacion: "a", col2015: 1, col2016: 2, col2017: 3 },
  { agrupacion: "b", col2015: 4, col2016: 6, col2017: 5 },
  { agrupacion: "c",                         col2017: 7 },
]

If these gaps in data can occur you'll want to change:如果可能出现这些数据空白,您需要更改:

if (!yearData || colYear in yearData)

Into:进入:

if (!yearData || agrupacion != yearData.agrupacion || colYear in yearData)

To ensure that a new yearData object is used if either agrupacion is different or col<year> is already present.如果agrupacion不同或col<year>已经存在,则确保使用新的yearData对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM