有一個需求是在前端部分完成篩選功能,一次拿到所有數據,然後根據條件篩選。通常情況下篩選是後臺給接口,在數據量不大的情況下,也有人可能會遇到前端篩選這樣的情況。
一般情況下的單條件篩選,數組的filter方法就能夠滿足需求,本文討論的重點是多條件下的複合篩選,並列出了幾個相關知識點。
// 這個是例子中的被篩選數組
var aim = [
{name:'Anne', age: 23, gender:'female'},
{name:'Leila', age: 16, gender:'female'},
{name:'Jay', age: 19, gender:'male'},
{name:'Mark', age: 40, gender:'male'}
]
單條件單數據篩選
根據單個名字篩選,用filter方法,判斷name是否爲目標名字即可
// 根據單個名字篩選
function filterByName(aim, name) {
return aim.filter(item => item.name == name)
}
// 輸入 aim 'Leila' 期望輸出爲 [{name:'Leila', age: 16, gender:'female'}]
console.log(filterByName(aim,'leila'))
單條件多數據篩選
根據多個名字篩選,這裏是用for循環遍歷目標數組,然後用find方法找到後push到結果數組裏,用find方法是重名情況下也能得到想要的結果。for循環可以用數組的一些遍歷方法替代,代碼可以更簡化,示例就是大概表達個意思。
// 根據多個名字篩選
function filterByName1(aim, nameArr) {
let result = []
for(let i = 0; i < nameArr.length; i++) {
result.push(aim.find(item => item.name = nameArr[i]))
}
return result
}
// 輸入 aim ['Anne','Jay']
//期望輸出爲 [{name:'Anne', age: 23, gender:'female'},{name:'Jay', age: 19, gender:'male'}]
console.log(filterByName1(aim,['Leila','Jay']))
// 有BUG 改進後
多條件單數據篩選
根據單個名字或者單個年齡篩選,用filter方法,判斷條件之間是或的關係。
// 根據名字或者年齡篩選
function filterByName2(aim, name, age) {
return aim.filter(item => item.name == name || item.age == age)
}
console.log(filterByName2(aim,'Leila',19))
多條件多數據篩選
我最初是用了很笨的雙for循環去做,發現很慢,而且並沒有達到預期的效果。具體的心路歷程已經太遙遠,簡單介紹以下這個篩選算法。
首先是把篩選條件都塞到一個對象裏,用object對象的keys方法獲取到篩選的條件名,及需要篩選的是哪個條件,是name?age? gender?
然後使用filter方法對目標數據進行篩選,?如下⬇️
根據名字和年齡多元素篩選
//根據名字和年齡多元素篩選
export function multiFilter(array, filters) {
const filterKeys = Object.keys(filters)
// filters all elements passing the criteria
return array.filter((item) => {
// dynamically validate all filter criteria
return filterKeys.every(key => {
//ignore when the filter is empty Anne
if(!filters[key].length) return true
return !!~filters[key].indexOf(item[key])
})
})
}
/*
* 這段代碼並非我原創,感興趣的可以去原作者那裏點個贊
* 作者是:@author https://gist.github.com/jherax
* 這段代碼裏我只加了一行,解決部分篩選條件清空時候整體篩選失效的問題
*/
var filters = {
name:['Leila', 'Jay'],
age:[]
}
/* 結果:
* [{name: "Leila", age: 16, gender: "female"},
* {name: "Jay", age: 19, gender: "male"}]
*/
例如這裏,判斷每條數據的name值是否在filters.name數組裏,是的話返回true,判斷filters.age是空數組的話直接返回true,空數組是模擬了age條件被清空的情況,我們仍然能得到正確的篩選數據。