You learned to filter heroes according to attack type in the previous lesson. For this lesson, we’re going to continue filtering heroes based on the other two categories: primary attribute and roles.
Filtering by primary attribute
If there are two sets of filters, we want to get heroes that match both sets. This means we can run a second filter function on top of the first one.
We need to filter heroes according to roles, so we’ll pass heroes through another filter function.
filtersDiv.addEventListener('change', event => {
// ...
const filtered = heroes
.filter(/* filter by attack type */)
.filter(/* filter by primary attribute */)
.filter(hero => {
// ...
})
})
If the user did not check anything under the role category, we want to return all filtered heroes.
filtersDiv.addEventListener('change', event => {
// ...
const filtered = heroes
.filter(/* filter by attack type */)
.filter(/* filter by primary attribute */)
.filter(hero => {
if (selectedRoles.length === 0 ) return true
// ...
})
})
Getting a matched role
We know hero.roles is an array. We also know each role is in sentence case. We have to convert them into lowercase. So we’ll loop through the roles with map.
We want to check if any of the hero’s roles matches any of the user’s selected roles. Here, we can loop through heroRoles or selectedRoles. Either works.
Looping through selectedRoles make more sense to me.
filtersDiv.addEventListener('change', event => {
// ...
const filtered = heroes
.filter(/* filter by attack type */)
.filter(/* filter by primary attribute */)
.filter(hero => {
// ...
for (const role of selectedRoles) {
// ...
}
})
})
If role exists in heroRoles, we know the hero matches the criteria. We can return true. If all selected roles don’t exist in heroRoles, we know the hero doesn’t match the criteria, and we return false.
filtersDiv.addEventListener('change', event => {
// ...
const filtered = heroes
.filter(/* filter by attack type */)
.filter(/* filter by primary attribute */)
.filter(hero => {
// ...
for (const role of selectedRoles) {
if (heroRoles.includes(role)) return true
}
return false
})
})
You can also use an array method called some to do the same thing.