others - Javascript - 在内部数组上,如何基于内部数组筛选外部数组?

106 2

{


"areas": [


 {


"name":"area 1",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": true


 }


 ]


 },


 {


"name":"area 2",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": true


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": false


 }


 ]


 },


 {


"name":"area 3",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 }


 ]


 },


 {


"name":"area 4",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": true


 }


 ]


 }


 ]


}



结果必须仅包含仅有选定属性等于true的服务的区域,并且必须指出这些区域而不改变原始数组。

使用这里代码


const result = areas.filter(area =>


 services.some(srv => srv.selected == true)


);



这就是我想要的:


{


"areas": [


 {


"name":"area 1",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 4",


"selected": true


 }


 ]


 },


 {


"name":"area 2",


"services": [


 {


"label":"srv 2",


"selected": true


 }


 ]


 },


 {


"name":"area 4",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 3",


"selected": true


 }


 ]


 }


 ]


}



谢谢

时间: 原作者:

67 1

为了避免改变原始对象,映射每个input.areas项目,以便将其转换为务中仅选择了truthy的对象,然后根据services属性是否包含项目进行筛选:


const transform = (input) => input.areas


 .map(({ name, services }) => ({


 name,


 services: services.filter(({ selected }) => selected)


 }))


 .filter(({ services }) => services.length);



const input = {


"areas": [


 {


"name":"area 1",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": true


 }


 ]


 },


 {


"name":"area 2",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": true


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": false


 }


 ]


 },


 {


"name":"area 3",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 }


 ]


 },


 {


"name":"area 4",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": true


 }


 ]


 }


 ]


};


console.log(transform(input));
原作者:
70 5

你可以减少数组,只获取services在筛选后有某些项的部分。


var data = { areas: [{ name:"area 1", services: [{ label:"srv 1", selected: true }, { label:"srv 2", selected: false }, { label:"srv 3", selected: false }, { label:"srv 4", selected: true }] }, { name:"area 2", services: [{ label:"srv 1", selected: false }, { label:"srv 2", selected: true }, { label:"srv 3", selected: false }, { label:"srv 4", selected: false }] }, { name:"area 3", services: [{ label:"srv 1", selected: false }, { label:"srv 2", selected: false }, { label:"srv 3", selected: false }] }, { name:"area 4", services: [{ label:"srv 1", selected: true }, { label:"srv 2", selected: false }, { label:"srv 3", selected: true }] }] },


 result = data.areas.reduce((r, o) => {


 var services = o.services.filter(({ selected }) => selected);


 if (services.length) r.push(Object.assign({}, o, { services }));


 return r;


 }, []);



console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
原作者:
143 0

你可以使用过滤器两次


const res = data.areas.filter(e => {


 e.services = e.services.filter(s => s.selected);


 return e.services.length;


});



console.log(res);

<script>


const data = {


"areas": [


 {


"name":"area 1",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": true


 }


 ]


 },


 {


"name":"area 2",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": true


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": false


 }


 ]


 },


 {


"name":"area 3",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 }


 ]


 },


 {


"name":"area 4",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": true


 }


 ]


 }


]


}


</script>
原作者:
88 0

你可以这样做


obj.areas.filter(area =>


 area.services = area.services.filter(srv => srv.selected == true)


);



原作者:
124 5

这应该足够了,你基本上可以使用Array#filter的组合。


const filterBySelectedServices = list => list


 .map(area => Object.assign({}, area, {


 services: area.services.filter(service => service.selected),


 }))


 .filter(area => area.services.length);



const data = {


"areas": [


 {


"name":"area 1",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": true


 }


 ]


 },


 {


"name":"area 2",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": true


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": false


 }


 ]


 },


 {


"name":"area 3",


"services": [


 {


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 }


 ]


 },


 {


"name":"area 4",


"services": [


 {


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": true


 }


 ]


 }


 ]


};



console.log('result', filterBySelectedServices(data.areas));
原作者:
131 2

你可以使用reduce,在不改变输入的情况下对内部数组进行filter


const input={"areas":[{"name":"area 1","services":[{"label":"srv 1","selected":true},{"label":"srv 2","selected":false},{"label":"srv 3","selected":false},{"label":"srv 4","selected":true}]},{"name":"area 2","services":[{"label":"srv 1","selected":false},{"label":"srv 2","selected":true},{"label":"srv 3","selected":false},{"label":"srv 4","selected":false}]},{"name":"area 3","services":[{"label":"srv 1","selected":false},{"label":"srv 2","selected":false},{"label":"srv 3","selected":false}]},{"name":"area 4","services":[{"label":"srv 1","selected":true},{"label":"srv 2","selected":false},{"label":"srv 3","selected":true}]}]}



const areas = input.areas.reduce((r, a) => {


 const services = a.services.filter(s => s.selected)



 if(services.length)


 r.push({ ...a, services });



 return r


}, [])



console.log({ areas })
原作者:
74 1

你可以使用reducefilter,只接受服务在过滤后有某些项的元素,


let data = {"areas": [{"name":"area 1","services": [{"label":"srv 1","selected": true},{"label":"srv 2","selected": false},{"label":"srv 3","selected": false},{"label":"srv 4","selected": true}]},{"name":"area 2","services": [{"label":"srv 1","selected": false},{"label":"srv 2","selected": true},{"label":"srv 3","selected": false},{"label":"srv 4","selected": false}]},{"name":"area 3","services": [{"label":"srv 1","selected": false},{"label":"srv 2","selected": false},{"label":"srv 3","selected": false}]},{"name":"area 4","services": [{"label":"srv 1","selected": true},{"label":"srv 2","selected": false},{"label":"srv 3","selected": true}]}]}



let final = data.areas.reduce((op, inp) => {


 let services = inp.services.filter( ({selected}) => selected )


 if(services.length) op.push({...inp, services})


 return op


},[])



console.log(final)
原作者:
137 3

你可以在过滤器的回调中过滤,如下所示:


let data = {"areas": [{"name":"area 1","services": [{"label":"srv 1","selected": true}, {"label":"srv 2","selected": false}, {"label":"srv 3","selected": false}, {"label":"srv 4","selected": true}]}, {"name":"area 2","services": [{"label":"srv 1","selected": false}, {"label":"srv 2","selected": true}, {"label":"srv 3","selected": false}, {"label":"srv 4","selected": false}]}, {"name":"area 3","services": [{"label":"srv 1","selected": false}, {"label":"srv 2","selected": false}, {"label":"srv 3","selected": false}]}, {"name":"area 4","services": [{"label":"srv 1","selected": true}, {"label":"srv 2","selected": false}, {"label":"srv 3","selected": true}]}]};



const result = data.areas.filter(area => {


 // filter area services 


 let selectedServices = area.services.filter(service => {


 return service.selected;


 });



 // If the area has selected services


 if (selectedServices.length) {


 // Save the selected services to area.services


 area.services = selectedServices;


 return true;


 } else {


 // Do not select the area


 return false;


 }


});



console.log(result);

然而,如果@CodeManiac指出,这会变异原始数组,如果你想保留它,然后使用reduce : data.areas.reduce()而不是data.areas.filter()

原作者:
98 1

第一次筛选后,你可以按如下所示过滤每个索引中的服务:


result.forEach((item)=>{


 item.services = item.services.filter((service)=>service.selected==true);


})



原作者:
114 1

请尝试如下所示:


const data = {


"areas": [{


"name":"area 1",


"services": [{


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": true


 }


 ]


 },


 {


"name":"area 2",


"services": [{


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": true


 },


 {


"label":"srv 3",


"selected": false


 },


 {


"label":"srv 4",


"selected": false


 }


 ]


 },


 {


"name":"area 3",


"services": [{


"label":"srv 1",


"selected": false


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": false


 }


 ]


 },


 {


"name":"area 4",


"services": [{


"label":"srv 1",


"selected": true


 },


 {


"label":"srv 2",


"selected": false


 },


 {


"label":"srv 3",


"selected": true


 }


 ]


 }


 ]


}



const res = data.areas.map(x => {


 // Destructure the name and services from the current callback object


 const { name, services } = x;



 // Now filter the services object where the .selected property is set to true


 const filteredServices = services.filter(x => x.selected);



 if (filteredServices.length) {


 // Project your desired object


 return { name: name, services: filteredServices }


 }


})


// Also filter for empty services


.filter(x => x);



console.log(res);
原作者:
...