I have a problem trying to convert current JSON structure to another
var data = [
{
"url": "asset/01.flv",
"pic": "asset/01.jpg"
},
{
"url": "asset/02.flv",
"pic": "asset/02.jpg"
},
{
"url": "asset/03.flv",
"pic": "asset/03.jpg"
},
{
"url": "asset/04.flv|asset/05.flv|asset/06.flv|asset/07.flv|asset/08.flv",
"pic": "asset/04.jpg|asset/05.jpg|asset/06.jpg|asset/07.jpg|asset/08.jpg"
},
{
"url": "asset/09.flv|asset/10.flv",
"pic": "asset/09.jpg|asset/10.jpg"
}
]
I want to convert data to an output structure like this.
Here's the target with just the result I want to achieve.
var data = [
{
"url": "asset/01.flv",
"pic": "asset/01.jpg"
},
{
"url": "asset/02.flv",
"pic": "asset/02.jpg"
},
{
"url": "asset/03.flv",
"pic": "asset/03.jpg"
},
{
"url": "asset/04.flv",
"pic": "asset/04.jpg"
},
{
"url": "asset/05.flv",
"pic": "asset/05.jpg"
},
{
"url": "asset/06.flv",
"pic": "asset/06.jpg"
},
{
"url": "asset/07.flv",
"pic": "asset/07.jpg"
},
{
"url": "asset/08.flv",
"pic": "asset/08.jpg"
},
{
"url": "asset/09.flv",
"pic": "asset/09.jpg"
},
{
"url": "asset/10.flv",
"pic": "asset/10.jpg"
}
]
It is diffcult for me, could someone help me in this matter? I've tried for several hours. Using lodash or underscore or plain JS is ok. Thanks in advance.
You can do it with the use of Array#reduce
. The idea is to loop over the array and check if the url
and pic
has |
in their values.
If so, split the value and push all items to the result. If not, push the url
and pic
as it is.
var data = [{"url":"asset/01.flv","pic":"asset/01.jpg"},{"url":"asset/02.flv","pic":"asset/02.jpg"},{"url":"asset/03.flv","pic":"asset/03.jpg"},{"url":"asset/04.flv|asset/05.flv|asset/06.flv|asset/07.flv|asset/08.flv","pic":"asset/04.jpg|asset/05.jpg|asset/06.jpg|asset/07.jpg|asset/08.jpg"},{"url":"asset/09.flv|asset/10.flv","pic":"asset/09.jpg|asset/10.jpg"}];
var result = data.reduce((r, {url, pic}) => {
if (url.includes('|') && pic.includes('|')) {
var urls = url.split('|');
var pics = pic.split('|');
urls.forEach((u, i) => {
r.push({url: u, pic: pics[i]});
});
} else {
r.push({url, pic})
}
return r;
}, []);
console.log(result);
You can use of an Array.reduce
to do the manipulation yourself.
const arr = [{
"url": "asset/01.flv",
"pic": "asset/01.jpg"
},
{
"url": "asset/02.flv",
"pic": "asset/02.jpg"
},
{
"url": "asset/03.flv",
"pic": "asset/03.jpg"
},
{
"url": "asset/04.flv|asset/05.flv|asset/06.flv|asset/07.flv|asset/08.flv",
"pic": "asset/04.jpg|asset/05.jpg|asset/06.jpg|asset/07.jpg|asset/08.jpg"
},
{
"url": "asset/09.flv|asset/10.flv",
"pic": "asset/09.jpg|asset/10.jpg"
}
];
console.log(arr.reduce((tmp, {
pic,
url,
}) => {
const urlSplit = url.split('|');
return [
...tmp,
...pic.split('|').map((x, xi) => ({
pic: x,
url: urlSplit[xi],
})),
];
}, []));
IMHO, you can do something like this using Array#reduce()
:
var data = [{"url":"asset/01.flv","pic":"asset/01.jpg"},{"url":"asset/02.flv","pic":"asset/02.jpg"},{"url":"asset/03.flv","pic":"asset/03.jpg"},{"url":"asset/04.flv|asset/05.flv|asset/06.flv|asset/07.flv|asset/08.flv","pic":"asset/04.jpg|asset/05.jpg|asset/06.jpg|asset/07.jpg|asset/08.jpg"},{"url":"asset/09.flv|asset/10.flv","pic":"asset/09.jpg|asset/10.jpg"}];
var parsedData = data.reduce((accumulator, e) => {
e['url'].split('|').forEach((ele, i) => {
accumulator.push({"url":ele, "pic": e['pic'].split('|')[i]})
})
return accumulator;
}, [])
console.log(parsedData);
Same solution using Underscore.js's _.zip()
function.
var data = [{"url":"asset/01.flv","pic":"asset/01.jpg"},{"url":"asset/02.flv","pic":"asset/02.jpg"},{"url":"asset/03.flv","pic":"asset/03.jpg"},{"url":"asset/04.flv|asset/05.flv|asset/06.flv|asset/07.flv|asset/08.flv","pic":"asset/04.jpg|asset/05.jpg|asset/06.jpg|asset/07.jpg|asset/08.jpg"},{"url":"asset/09.flv|asset/10.flv","pic":"asset/09.jpg|asset/10.jpg"}];
var parsedData = data.reduce((accumulator, e) => {
return accumulator.concat(...(_.zip(e['url'].split('|'), e['pic']
.split('|'))
.map(([url, pic]) => ({url, pic}))))
}, []);
console.log(parsedData)
<script src="https://underscorejs.org/underscore-min.js"></script>
How about simply use a flatmap
with zipWith
??
const sortedData = _.flatMap(data, obj =>
_.zipWith(
obj.url.split("|"),
obj.pic.split("|"),
(url, pic) => ({url, pic})
)
);
var data = [
{
"url": "asset/01.flv",
"pic": "asset/01.jpg"
},
{
"url": "asset/02.flv",
"pic": "asset/02.jpg"
},
{
"url": "asset/03.flv",
"pic": "asset/03.jpg"
},
{
"url": "asset/04.flv|asset/05.flv|asset/06.flv|asset/07.flv|asset/08.flv",
"pic": "asset/04.jpg|asset/05.jpg|asset/06.jpg|asset/07.jpg|asset/08.jpg"
},
{
"url": "asset/09.flv|asset/10.flv",
"pic": "asset/09.jpg|asset/10.jpg"
}
]
var res = _.flatMap(data, o=>_.zipWith(o.url.split("|"), o.pic.split("|"), (url, pic) => ({url, pic})));
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With