Suppose there are two objects.
const a = [
{ id: '1-1-1', name: 'a111' },
{ id: '1-1-2', name: 'a112' },
{ id: '1-2-1', name: 'a121' },
{ id: '1-2-2', name: 'a122' },
{ id: '2-1-1', name: 'a211' },
{ id: '2-1-2', name: 'a212' }
]
const b = ['1-1', '1-2', '2-1']
and the result
{
'1-1':[
{ id: '1-1-1', name: 'a111' },
{ id: '1-1-2', name: 'a112' },
],
'1-2':[
{ id: '1-2-1', name: 'a121' },
{ id: '1-2-2', name: 'a122' },
],
'2-1':[
{ id: '2-1-1', name: 'a211' },
{ id: '2-1-2', name: 'a212' },
]
}
Basically, I want to group the data.
I use includes
to check if the item from b
to match the id from a
. Then construct the new array.
This is my attempt( fiddle ):
return b.map(item => a.map(jtem => {
if(jtem.id.includes(item)){
return {
[item]: jtem
}
}
}))
For somehow, it doesn't work.
and, is there a clever way to avoid the nested for
loop or map
function?
You can do that in following steps:
Apply reduce()
on the array b
During each iteration use filter()
on the the array a
a
which starts with item of b
using String.prototype.startsWith()
ac
and return ac
const a = [ { id: '1-1-1', name: 'a111' }, { id: '1-1-2', name: 'a112' }, { id: '1-2-1', name: 'a121' }, { id: '1-2-2', name: 'a122' }, { id: '2-1-1', name: 'a211' }, { id: '2-1-2', name: 'a212' } ] const b = ['1-1', '1-2', '2-1'] let res = b.reduce((ac,b) => { ac[b] = a.filter(x => x.id.startsWith(b)); return ac; },{}) console.log(res)
As suggested by @Falco is the comments that It would be better to scan over the a
once as its large. So here is that version.Actually its better regarding performance
const a = [ { id: '1-1-1', name: 'a111' }, { id: '1-1-2', name: 'a112' }, { id: '1-2-1', name: 'a121' }, { id: '1-2-2', name: 'a122' }, { id: '2-1-1', name: 'a211' }, { id: '2-1-2', name: 'a212' } ] const b = ['1-1', '1-2', '2-1'] let res = a.reduce((ac,x) => { let temp = b.find(y => x.id.startsWith(y)) if(!ac[temp]) ac[temp] = []; ac[temp].push(x); return ac; },{}) console.log(res)
Note : startsWith
is not supported by IE So you can create polyfill using indexOf
if(!String.prototype.startWith){ String.prototype.startsWith = function(str){ return this.indexOf(str) === 0 } }
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.