2

based on this question Group array items using object

I quoted from this answer, answered by https://stackoverflow.com/users/1094311/1983

so I get data from this jquery then I parsed it, after that I push it to variable

the data that I get from myurl is like this

{"pname":"some1","datax":2.0643278,"prov":"11","datay":1},{"pname":"some1","datax":3.2142857142857144,"prov":"11","datay":1},{"pname":"some2","datax":1.125,"prov":"12","datay":1},{"pname":"some2","datax":1.6666666666666667,"prov":"12","datay":2}

this is how my array begin

$(document).ready(function(){
    $.ajax({
                        url: "myurl",
                        method: "GET",
                        success: function(data) {

var parsedJSON = JSON.parse(data);

var result1 = [
  (function(data) {
    let tmp = [];

    data.forEach(e => {
      tmp.push({
        type: "firstid",
        prov: e.prov,
        name: e.pname,
        showInLegend:false,
        dataPoints:[{x:e.datax, y:e.datay}],
      })
    });

    return tmp;
  })(parsedJSON)
];

from there I got result1[0] and if I console log it, it will be like this

[        { type: "firstid",
           prov: 11,
           name: some1,
           showInLegend:false,
           dataPoints:[{x:2.0643278, y:1}] 
         },
         { type: "firstid",
           prov: 11,
           name: some1,
           showInLegend:false,
           dataPoints:[{x:3.2142857142857144, y:1}] 
         },
         { type: "firstid",
           prov: 12,
           name: some2,
           showInLegend:false,
           dataPoints:[{x:1.125, y:1}] 
         },
         { type: "firstid",
           prov: 12,
           name: some2,
           showInLegend:false,
           dataPoints:[{x:1.6666666666666667, y:1}] 
         }]

I want to get some array to be like this when I console log it :

[        { type: "firstid",
           prov: 11,
           name: some1,
           showInLegend:false,
           dataPoints:[ {x:2.0643278, y:1}, 
                        {x:3.2142857142857144, y:1}] 
         },
         { type: "firstid",
           prov: 12,
           name: some2,
           showInLegend:false,
           dataPoints:[ {x:1.125, y:1}, 
                        {x:1.6666666666666667, y:1}] 
         }]

I spent my time trying to figure it out with array merge but it seems I can't figure it out, any help would be nice

isherwood
  • 58,414
  • 16
  • 114
  • 157
Attaroqqi
  • 77
  • 5

3 Answers3

1

Based on your approach I will try to just push if the element is not present, if it is present, then push to the dataPoints array on the existing element. I haven't tried this, but it could work.

data.forEach(e => {
    const tempIndex = tmp.findIndex(el => el.prov === e.prov);
    if (tempIndex) {
        tmp[tempIndex].dataPoints.push({ x: e.datax, y: e.datay });
    } else {
        tmp.push({
            type: "firstid",
            prov: e.prov,
            name: e.pname,
            showInLegend: false,
            dataPoints: [{ x: e.datax, y: e.datay }],
        })
    }
});

Please let me know if this edited approach is better

Yalung Tang
  • 613
  • 4
  • 10
1

Using Array.prototype.reduce and Array.prototype.find should do the trick.

reduce loops over every element in the array. It starts with an empty array: []. The code then checks with find if the elements is already in the new array. If so add the dataPoints to the existing array. If it doesn't exist, push the object to the new array.

const obj = [{"pname":"some1","datax":2.0643278,"prov":"11","datay":1},{"pname":"some1","datax":3.2142857142857144,"prov":"11","datay":1},{"pname":"some2","datax":1.125,"prov":"12","datay":1},{"pname":"some2","datax":1.6666666666666667,"prov":"12","datay":2}];

objReduced = obj.reduce((acc, cur) => {
  const dbItem = acc.find( element => element.prov === cur.prov);
  if (dbItem)
  {
    dbItem.dataPoints.push({x: cur.datax, y: cur.datay});
  }
  else
  {
    acc.push({  type: "firstid",
                prov: cur.prov,
                name: cur.pname,
                showInLegend: false,
                dataPoints: [{x: cur.datax, y: cur.datay}]
    });
  }
  return acc;
}, []);

console.log(objReduced);
obj = [{
    type: "firstid",
    prov: 11,
    name: "some1",
    showInLegend: false,
    dataPoints: [{
      x: 2.0643278,
      y: 1
    }]
Mouser
  • 13,132
  • 3
  • 28
  • 54
0

This one will also check for duplicate items in dataPoints array before merging them:

const data = [{
    type: "firstid",
    prov: 11,
    name: "some1",
    showInLegend: false,
    dataPoints: [{
      x: 2.0643278,
      y: 1
    }]
  },
  {
    type: "firstid",
    prov: 11,
    name: "some1",
    showInLegend: false,
    dataPoints: [{
      x: 3.2142857142857144,
      y: 1
    }]
  },
  {
    type: "firstid",
    prov: 12,
    name: "some2",
    showInLegend: false,
    dataPoints: [{
      x: 1.125,
      y: 1
    }]
  },
  {
    type: "firstid",
    prov: 12,
    name: "some2",
    showInLegend: false,
    dataPoints: [{
      x: 1.6666666666666667,
      y: 1
    }]
  }
];

const res = Object.values(data.reduce((acc, curr) => {
  const groupKey = ['type', 'prov', 'name', 'showInLegend'].map(x => curr[x]).join('-');

  if (!acc[groupKey]) {
    acc[groupKey] = curr;
  } else {
    for (const { x: currX, y: currY } of curr.dataPoints) {
      for (const {  x: accX, y: accY } of acc[groupKey].dataPoints) {
        if ((currX + '-' + currY) !== (accX + '-' + accY)) {
          acc[groupKey].dataPoints.push({ x: currX, y: currY });
        }
      }
    }
  }
  return acc;
}, {}));

console.log(res);
Kunal Mukherjee
  • 5,775
  • 3
  • 25
  • 53