[英]How do I retrieve a list of active items from an Array?
I'm trying to get a list of employees who only have active hobbies and whose role is of type 'A'. 我正在尝试列出仅拥有活跃兴趣并且角色为“ A”型的员工。
I tried using the below query but without any success. 我尝试使用以下查询,但未成功。
What am I doing wrong? 我究竟做错了什么?
// Get all the employees with active hobbies and have a role of 'A' var employees = people.find(item => item.key === 'Employees').employees.map(emp => emp.hobbies).filter(hobby => hobby.filter(h => h.active === true && h.roles.includes('A'))); console.log(employees);
<script> var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }]; </script>
Update 更新资料
When I added more employees with new hobbies to the array, the accepted answer fails to produce the correct output. 当我向阵列中添加更多具有新爱好的员工时,被接受的答案无法产生正确的输出。 Why does this happen?
为什么会这样?
var people = [{
key: 'Employees',
employees: [{
name: 'Steve',
age: 50,
hobbies: [{
active: true,
name: 'skating',
roles: ['C', 'A']
},
{
active: false,
name: 'skating',
roles: ['C', 'A']
},
{
active: true,
name: 'snooker',
roles: ['C', 'A']
},
{
active: true,
name: 'darts',
roles: ['C', 'A']
}
]
},{
name: 'joe',
age: 20,
hobbies: [{
active: true,
name: 'skating',
roles: ['C', 'A']
}
]
}, {
name: 'amy',
age: 32,
hobbies: [{
'active': true,
name: 'surfing',
roles: ['A']
}
]
}, {
name: 'kate',
age: 34,
hobbies: [{
active: true,
name: 'running',
roles: ['C']
}, {
name: 'Chess',
active: false,
roles: ['C', 'A']
}
]
}
]
}
];
var employees = people.find(item => item.key === 'Employees').employees.filter(employee => employee.hobbies.every(h => h.active && h.roles.includes('A')));
If you do this: 如果您这样做:
.map(emp => emp.hobbies).filter(hobby =>
you map every employee to its hobbies, which fill result in a 2D
array: 您将每个员工映射到其兴趣爱好,从而将结果填充为
2D
数组:
[[ { active: true }, { active: false } ], [/*...*/]]
Therefore hobby
is not one hobby but an array of hobbies. 因此,
hobby
不是一种爱好,而是一系列爱好。
You said 你说
I'm trying to get a list of employees
我正在尝试获取员工名单
... which means you actually don't want to .map
to the hobbies, but rather .filter
the employees and check if ever
hobby fullfills certain rules: ......这意味着你其实不想
.map
的爱好,而是.filter
员工,并检查是否ever
爱好fullfills一定的规则:
const employees = people.find(({ key }) => key === "Employees").employees;
const isActive = hobby => hobby.active && hobby.roles.includes("A");
const result = employees.filter(emp => emp.hobbies.every(isActive));
Things go wrong where you map the employees to their hobbies: this will make your final result consist of hobbies, not employees. 当您将员工映射到他们的兴趣爱好时,事情会出错:这将使您的最终结果由兴趣爱好而不是员工组成。
You need to stick to the employee level: 您需要坚持员工级别:
var people = [{key: 'Employees',employees: [{ name: 'joe', age: 20, hobbies: [{'active': true, name: 'skating', roles: ['C', 'A'] }] },{ name: 'amy', age: 32, hobbies: [{'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{'active': true, name: 'running', roles: ['C']}, {name: 'Chess', active: false, roles: ['C','A']}] }]}]; var employees = people.find(item => item.key === 'Employees').employees .filter(employee => employee.hobbies.every(h => h.active && h.roles.includes('A'))); console.log(employees);
In an expression there is no need to compare a boolean property with true
. 在表达式中,无需将布尔属性与
true
进行比较。 Just use the property ( active
in this case). 只需使用该属性(在这种情况下为
active
)即可。
Use .some
instead of .every
if the requirement is that employees have at least one such hobby, instead of requiring that all their hobbies comply with the condition. 如果要求员工至少有一个这样的爱好,请使用
.some
而不是.every
,而不是要求所有爱好都符合条件。
.map(emp => emp.hobbies)
returns an array of the hobbies, so the value of employees
will be the filtered list of hobbies, not the employees that have those hobbies. .map(emp => emp.hobbies)
返回兴趣爱好的数组,因此, employees
的价值将是兴趣爱好的过滤列表,而不是拥有这些兴趣爱好的员工。 You need to filter the employees, not map them. 您需要过滤员工,而不是映射他们。
// Get all the employees with active hobbies and have a role of 'A' var employees = people.find(item => item.key === 'Employees').employees.filter(emp => emp.hobbies.every(h => h.active && h.roles.includes('A'))); console.log(employees);
<script> var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }]; </script>
You can simply do one call to Array.prototype.filter
which checks the conditions you mentioned: 您只需对
Array.prototype.filter
进行一次调用即可检查您提到的条件:
person.hobbies.every(y => y.active) && person.hobbies.every(z => z.roles.includes('A'))
var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }]; let employees = people[0].employees.filter(x => x.hobbies.every(y => y.active) && x.hobbies.every(z => z.roles.includes('A')) ) console.log(employees);
You can use map
& filter
: 您可以使用
map
和filter
:
var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }]; const result = people.filter(x => x.key == 'Employees') .map(({employees}) => employees.filter(x => x.hobbies.some(y => y.active && y.roles.includes('A')))) console.log(result)
you could also use reduce
& filter
: 您还可以使用
reduce
& filter
:
var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }]; const result = people.filter(x => x.key == 'Employees').reduce((r,{employees}) => { r.push(employees.filter(x => x.hobbies.some(y => y.active && y.roles.includes('A')))) return r }, []) console.log(result)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.