我有一个像这样的json,我想获得具有几乎一项服务的所有区域,这些区域的selected属性等于true。
{
"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)
);
我获得了所有区域,但是在这些区域内,我拥有了所有服务(选择为true和选择false)。
这是我想要的:
{
"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
}
]
}
]
}
谢谢
答案 0 :(得分:2)
为避免变异原始对象,请map
的每个input.areas
项目将其变成其selected
中只有真实services
的对象,然后将{{1} } filter
属性中是否包含任何项目:
services
答案 1 :(得分:1)
您可以缩小数组,并仅过滤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; }
答案 2 :(得分: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>
答案 3 :(得分:0)
您可以做到
obj.areas.filter(area =>
area.services = area.services.filter(srv => srv.selected == true)
);
答案 4 :(得分:0)
这应该足够了,
您基本上可以结合使用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));
答案 5 :(得分:0)
您可以使用reduce
和filter
并仅采用过滤后服务中包含某些项目的那些元素
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)
答案 6 :(得分:0)
您可以使用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 })
答案 7 :(得分:0)
尝试这样的事情:
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);
答案 8 :(得分:0)
您可以在过滤器的回调内部进行过滤,如下所示:
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()
答案 9 :(得分:0)
在完成第一次过滤后,可以按以下步骤过滤每个索引中的服务:
result.forEach((item)=>{
item.services = item.services.filter((service)=>service.selected==true);
})