Home > Software design >  Split JSON array based on the type of suggestion it's receiving
Split JSON array based on the type of suggestion it's receiving

Time:12-01

So I have the following JSON array

[
  {
    "characterID": 0,
    "description": "Series 1",
    "id": 1,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "SERIES",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Series 2",
    "id": 2,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "SERIES",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Character 1",
    "id": 1,
    "seriesID": 25,
    "status": "ACCEPTED",
    "type": "CHARACTER",
    "userID": 1
  },
  {
    "URL": "https://previews.123rf.com/images/aquir/aquir1311/aquir131100316/23569861-sample-grunge-red-round-stamp.jpg",
    "characterID": 853,
    "description": "Picture 1",
    "id": 1,
    "seriesID": 25,
    "status": "ACCEPTED",
    "type": "IMAGE",
    "userID": 1
  },
  {
    "URL": "https://c.tenor.com/uEjQxCwAWfgAAAAC/sample.gif",
    "characterID": 1,
    "description": "Gif 1",
    "id": 1,
    "seriesID": 1,
    "status": "ACCEPTED",
    "type": "GIF",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Idea 1",
    "id": 1,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "IDEA",
    "userID": 1
  }
]

However I want to achieve splitting the arrays as follows

[
  {
    "characterID": 0,
    "description": "Series 1",
    "id": 1,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "SERIES",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Series 2",
    "id": 2,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "SERIES",
    "userID": 1
  }
]
[

  {
    "characterID": 0,
    "description": "Character 1",
    "id": 1,
    "seriesID": 25,
    "status": "ACCEPTED",
    "type": "CHARACTER",
    "userID": 1
  }
]

What I want to achieve is split the JSON in segments based on what type it contains within the array.

I am working in Javascript / Vue, if there's any solutions for this, would be appreciated.

CodePudding user response:

Array.reduce, will work nicely here.

Below is an example.

var data = JSON.parse('[{"characterID":0,"description":"Series 1","id":1,"seriesID":0,"status":"ACCEPTED","type":"SERIES","userID":1},{"characterID":0,"description":"Series 2","id":2,"seriesID":0,"status":"ACCEPTED","type":"SERIES","userID":1},{"characterID":0,"description":"Character 1","id":1,"seriesID":25,"status":"ACCEPTED","type":"CHARACTER","userID":1},{"URL":"https://previews.123rf.com/images/aquir/aquir1311/aquir131100316/23569861-sample-grunge-red-round-stamp.jpg","characterID":853,"description":"Picture 1","id":1,"seriesID":25,"status":"ACCEPTED","type":"IMAGE","userID":1},{"URL":"https://c.tenor.com/uEjQxCwAWfgAAAAC/sample.gif","characterID":1,"description":"Gif 1","id":1,"seriesID":1,"status":"ACCEPTED","type":"GIF","userID":1},{"characterID":0,"description":"Idea 1","id":1,"seriesID":0,"status":"ACCEPTED","type":"IDEA","userID":1}]');


const grouped = data.reduce((a, v) => {
  if (!a[v.type]) a[v.type] = [];
  a[v.type].push(v);
  return a;
}, {});

console.log(grouped);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You can use reduce to create a new object with type as keys:

var res = data.reduce((acc, val) => {
if (!acc[val.type]) {
    acc[val.type] = [val];
} else {
    acc[val.type].push(val)
}
return acc;

}, {})

The result will look something like:

{
   "SERIES":[
      {
         "characterID":0,
         "description":"Series 1",
         "id":1,
         "seriesID":0,
         "status":"ACCEPTED",
         "type":"SERIES",
         "userID":1
      },
      {
         "characterID":0,
         "description":"Series 2",
         "id":2,
         "seriesID":0,
         "status":"ACCEPTED",
         "type":"SERIES",
         "userID":1
      }
   ],
   "CHARACTER":[
      {
         "characterID":0,
         "description":"Character 1",
         "id":1,
         "seriesID":25,
         "status":"ACCEPTED",
         "type":"CHARACTER",
         "userID":1
      }
   ],
   "IMAGE":[
      {
         "URL":"https://previews.123rf.com/images/aquir/aquir1311/aquir131100316/23569861-sample-grunge-red-round-stamp.jpg",
         "characterID":853,
         "description":"Picture 1",
         "id":1,
         "seriesID":25,
         "status":"ACCEPTED",
         "type":"IMAGE",
         "userID":1
      }
   ],
   "GIF":[
      {
         "URL":"https://c.tenor.com/uEjQxCwAWfgAAAAC/sample.gif",
         "characterID":1,
         "description":"Gif 1",
         "id":1,
         "seriesID":1,
         "status":"ACCEPTED",
         "type":"GIF",
         "userID":1
      }
   ],
   "IDEA":[
      {
         "characterID":0,
         "description":"Idea 1",
         "id":1,
         "seriesID":0,
         "status":"ACCEPTED",
         "type":"IDEA",
         "userID":1
      }
   ]
}

CodePudding user response:

I am not sure if you want to split and store into separate arrays or not but, if thats the case you can try this:

const obj = [
  {
    "characterID": 0,
    "description": "Series 1",
    "id": 1,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "SERIES",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Series 2",
    "id": 2,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "SERIES",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Character 1",
    "id": 1,
    "seriesID": 25,
    "status": "ACCEPTED",
    "type": "CHARACTER",
    "userID": 1
  },
  {
    "URL": "https://previews.123rf.com/images/aquir/aquir1311/aquir131100316/23569861-sample-grunge-red-round-stamp.jpg",
    "characterID": 853,
    "description": "Picture 1",
    "id": 1,
    "seriesID": 25,
    "status": "ACCEPTED",
    "type": "IMAGE",
    "userID": 1
  },
  {
    "URL": "https://c.tenor.com/uEjQxCwAWfgAAAAC/sample.gif",
    "characterID": 1,
    "description": "Gif 1",
    "id": 1,
    "seriesID": 1,
    "status": "ACCEPTED",
    "type": "GIF",
    "userID": 1
  },
  {
    "characterID": 0,
    "description": "Idea 1",
    "id": 1,
    "seriesID": 0,
    "status": "ACCEPTED",
    "type": "IDEA",
    "userID": 1
  }
];

const seriesTypeObjs = [];

obj.map(eachObj => {
  if (eachObj.type === 'SERIES'){
    seriesTypeObjs.push(eachObj);
  }
});
console.log('Series Type Objs =>', seriesTypeObjs);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

You can use the same code to test for other type values too.

CodePudding user response:

The easiest way is using a utility library like lodash Specifically method groupBy

_.groupBy(data, 'type');// {SERIES: Array(2), CHARACTER: Array(1), IMAGE: Array(1), GIF: Array(1), IDEA: Array(1)}

UPDATE:(vanilla approach without any libraries) Solution Using The Map which is object holds key-value pairs key is the type and value is their entry group of that type with ?. Optional chaining and ?? Nullish coalescing operator

let map = new Map()
for(entry of data){
    const type = entry?.type ?? "untyped";
    map.set(type, [...map.get(type)??[],entry])
}
// Map(5) {'SERIES' => Array(2), 'CHARACTER' => Array(1), 'IMAGE' => Array(1), 'GIF' => Array(1), 'IDEA' => Array(1)}
  • Related