简体   繁体   中英

JSON.parse result to proper array of objects

after my JSON.parse I have this data

 data = [
  {
      "serviceType": "service1",
      "method": "close",
      "quantity": 56
  },
  {
      "serviceType": "service1",
      "method": "divert",
      "quantity": 175
  },
  {
      "serviceType": "service1",
      "method": "reverted",
      "quantity": 80
  },
  {
      "serviceType": "service2",
      "method": "close",
      "quantity": 15
  },
  {
      "serviceType": "service2",
      "method": "divert",
      "quantity": 149
  },
  {
      "serviceType": "service2",
      "method": "reverted",
      "quantity": 149
  },
  {
      "serviceType": "service3",
      "method": "close",
      "quantity": 87
  },....
  }
]

And I need it to be like data.json from this d3 example where categorie is my serviceType , being it the first property of every object (1 object per serviceType) and then the second property of every object should be an array of objects with the method and quantity.

I've been using forEach for every object in data and I'm pushing the first of every serviceType OK (without the 2nd property). The problem is I don't know how to update the object values (second property) inside the right object (according to the current serviceType ).

finalArray = [];
data.forEach(function (d, index) {
    var serviceType = d.serviceType;    
    const found = finalArray.some( el => el.serviceType === serviceType);
    if (!found) {
        var obj = createObj(d); //function returning an obj with the desired structure
        finalArray.push(obj);                
    }...
});

This is an example of how the conversion should end up being.

[
    {
        "serviceType": "service1", 
        "values": [
            {
                "quantity": 0, 
                "method": "close"
            }, 
            {
                "quantity": 4, 
                "method": "divert"
            }, 
            {
                "quantity": 12, 
                "method": "reverted"
            }, 
            {
                "quantity": 0, 
                "method": "checked"
            }
        ]
    }, 
    {
        "serviceType": "service2", 
        "values": [
            {
                "quantity": 1, 
                "method": "close"
            }, 
            {
                "quantity": 21, 
                "method": "divert"
            }, 
            {
                "quantity": 13, 
                "method": "reverted"
            },  
            {
                "quantity": 6, 
                "method": "checked"
            }
        ]
    }, ...

You could take a Map and group same serviceType . Later build an a array with categorie and values properties.

 var data = [{ serviceType: "service1", method: "close", quantity: 56 }, { serviceType: "service1", method: "divert", quantity: 175 }, { serviceType: "service1", method: "reverted", quantity: 80 }, { serviceType: "service2", method: "close", quantity: 15 }, { serviceType: "service2", method: "divert", quantity: 149 }, { serviceType: "service2", method: "reverted", quantity: 149 }, { serviceType: "service3", method: "close", quantity: 87 }], result = Array.from( data.reduce((m, { serviceType, ...o }) => m.set(serviceType, [...(m.get(serviceType) || []), o]), new Map), ([categorie, values]) => ({ categorie, values }) ); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

You can get one object with grouped services using reduce method and then get array of values from that object.

 const data = [{"serviceType":"service1","method":"close","quantity":56},{"serviceType":"service1","method":"divert","quantity":175},{"serviceType":"service1","method":"reverted","quantity":80},{"serviceType":"service2","method":"close","quantity":15},{"serviceType":"service2","method":"divert","quantity":149},{"serviceType":"service2","method":"reverted","quantity":149},{"serviceType":"service3","method":"close","quantity":87}] const object = data.reduce((r, {serviceType: s, ...rest}) => { if(:r[s]) r[s] = {categorie,s: values; [rest]}. else r[s].values;push(rest); return r, }; {}). const result = Object;values(object). console;log(result);

Try this:

const result = [...new Set(data.map(e => e.serviceType))].map(serviceType => {
  const re = { serviceType };
  re.values = data
    .filter(e => e.serviceType === serviceType)
    .map(v => ({ method: v.method, quantity: v.quantity }));
  return re;
});

First I get all the serviceTypes (the part using ...new Set() ), then I create an object for each thereof consisting of the serviceType-name and the values, which I get by filtering out unrelated objects and dropping the serviceType-property of the related ones.

data.reduce((acc, value) => {
    var {serviceType, method, quantity} = value;
    var foundExisting = acc.find(v => v.serviceType == serviceType);

    if(foundExisting){
        foundExisting.values.push({method, quantity})
    } else {
        acc.push({serviceType, values: [{method, quantity}]})
    }

    return acc;
}, [])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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