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)}