Reputation: 67
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.
Upvotes: 5
Views: 150
Reputation: 4175
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>
Upvotes: 1
Reputation: 23859
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);
Upvotes: 1
Reputation: 10614
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>
Upvotes: 1
Reputation: 23515
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],
})),
];
}, []));
Upvotes: 1