JS實現(xiàn)數(shù)組過濾從簡單到多條件篩選
在上家公司工作的時候,有一個需求是在前端部分完成篩選功能,一次拿到所有數(shù)據(jù),然后根據(jù)條件篩選。通常情況下篩選是后臺給接口,在數(shù)據(jù)量不大的情況下,也有人可能會遇到前端篩選這樣的情況,特別寫了這篇文章分享給大家,有問題請指出,互相學習。
一般情況下的單條件篩選,數(shù)組的filter方法就能夠滿足需求,本文討論的重點是多條件下的復合篩選,并列出了幾個相關知識點。
以下是很多個🌰🌰🌰🌰
// 這個是例子中的被篩選數(shù)組 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'} ]
單條件單數(shù)據(jù)篩選
根據(jù)單個名字篩選,用filter方法,判斷name是否為目標名字即可
// 根據(jù)單個名字篩選 function filterByName(aim, name) { return aim.filter(item => item.name == name) } // 輸入 aim 'Leila' 期望輸出為 [{name:'Leila', age: 16, gender:'female'}] console.log(filterByName(aim,'leila'))
單條件多數(shù)據(jù)篩選
根據(jù)多個名字篩選,這里是用for循環(huán)遍歷目標數(shù)組,然后用find方法找到后push到結果數(shù)組里,用find方法是重名情況下也能得到想要的結果。for循環(huán)可以用數(shù)組的一些遍歷方法替代,代碼可以更簡化,示例就是大概表達個意思。
// 根據(jù)多個名字篩選 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 改進后
多條件單數(shù)據(jù)篩選
根據(jù)單個名字或者單個年齡篩選,用filter方法,判斷條件之間是或的關系。
// 根據(jù)名字或者年齡篩選 function filterByName2(aim, name, age) { return aim.filter(item => item.name == name || item.age == age) } console.log(filterByName2(aim,'Leila',19))
多條件多數(shù)據(jù)篩選
我最初是用了很笨的雙for循環(huán)去做,發(fā)現(xiàn)很慢,而且并沒有達到預期的效果。具體的心路歷程已經(jīng)太遙遠,簡單介紹以下這個篩選算法。
首先是把篩選條件都塞到一個對象里,用object對象的keys方法獲取到篩選的條件名,及需要篩選的是哪個條件,是name?age? gender?
然后使用filter方法對目標數(shù)據(jù)進行篩選,🌰如下⬇️
根據(jù)名字和年齡多元素篩選
//根據(jù)名字和年齡多元素篩選 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]) }) }) } /* * 這段代碼并非我原創(chuàng),感興趣的可以去原作者那里點個贊 * 作者是:@author https://gist.github.com/jherax * 這段代碼里我只加了一行,解決部分篩選條件清空時候整體篩選失效的問題 */ var filters = { name:['Leila', 'Jay'], age:[] } /* 結果: * [{name: "Leila", age: 16, gender: "female"}, * {name: "Jay", age: 19, gender: "male"}] */
例如這里,判斷每條數(shù)據(jù)的name值是否在filters.name數(shù)組里,是的話返回true,判斷filters.age是空數(shù)組的話直接返回true,空數(shù)組是模擬了age條件被清空的情況,我們?nèi)匀荒艿玫秸_的篩選數(shù)據(jù)。
知識點1: Object.key() 獲取數(shù)組索引或者對象屬性
var arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); // ["0", "1", "2"] var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj)); // ["0", "1", "2"] var anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj)); // ["2", "7", "100"] 猜猜為啥?
知識點2: js里的falsy
falsy : 0 , false, "", null, undefined, NaN
在判斷語句中,只有上面6種情況會是false,其余的都是true
var a; if(a!=null&&typeof(a)!=undefined&&a!=''){ //a有內(nèi)容才執(zhí)行的代碼 } if(!!a){ //a有內(nèi)容才執(zhí)行的代碼... }
知識點3: Array.every 與 Array.some的區(qū)別
我的理解是在遍歷數(shù)組的時候:
- Array.every的條件是「與」的關系,全真為真,及條件全為true則為true,有一個false就返回false
- Array.some的條件是「或」的關系,有真為真,條件有一個true就返回true,條件全為false的時候才返回false
下面舉個🌰
// 判斷每個名字都為Anne? let dataEvery = aim.every(item => item.name === 'Anne') // false let dataEvery = aim.some(item => item.name === 'Anne') // true // 判斷每個名字都是字符串? let dataEvery = aim.every(item => typeof item.name === 'string') // true let dataEvery = aim.some(item => typeof item.name === 'string') // true
知識點4: 數(shù)組的深拷貝與淺拷貝
最近參與一些前端的面試工作,深拷貝與淺拷貝是我最愛問的問題之一。一個問題就考察了數(shù)據(jù)類型,數(shù)組操作,遞歸算法等。
因為數(shù)組是js里的引用類型,單純復制時復制的是其引用關系。在對獲取的數(shù)據(jù)進行篩選時,我并不希望影響原始數(shù)據(jù),所以我要用到「深拷貝」得到與原始數(shù)據(jù)數(shù)據(jù)結構完全相同又相互獨立的數(shù)據(jù),而不是只復制其引用關系。
// 我常用方法,如果項目很大,不推薦 let obj1 = JSON.parse(JSON.stringify(obj)) // deepclone function deepClone(o1, o2) { for (let k in o2) { if (typeof o2[k] === 'object') { o1[k] = {}; deepClone(o1[k], o2[k]); } else { o1[k] = o2[k]; } } }
想一想:遞歸算法的優(yōu)化
這個知識點與本文關系不大。😄 抱歉之前的誤導。
這個是看掘金小冊前端面試指南看到的,講算法的時候提了一下遞歸算法的優(yōu)化,初見的時候又被驚艷到,還沒有在項目里用到。感興趣的可以試試,這個是斐波那契數(shù)列和??梢宰约涸跒g覽器里敲一下,試試不用緩存與用緩存的運算次數(shù)差別。
let count = 0; function fn(n) { let cache = {}; function _fn(n) { if (cache[n]) { return cache[n]; } count++; if (n == 1 || n == 2) { return 1; } let prev = _fn(n - 1); cache[n - 1] = prev; let next = _fn(n - 2); cache[n - 2] = next; return prev + next; } return _fn(n); } let count2 = 0; function fn2(n) { count2++; if (n == 1 || n == 2) { return 1; } return fn2(n - 1) + fn2(n - 2); }
到此這篇關于JS實現(xiàn)數(shù)組過濾從簡單到多條件篩選的文章就介紹到這了,更多相關JS 數(shù)組過濾內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
ant-design-pro使用qiankun微服務配置動態(tài)主題色的問題
這篇文章主要介紹了ant-design-pro使用qiankun微服務配置動態(tài)主題色,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03深入理解JavaScript系列(1) 編寫高質(zhì)量JavaScript代碼的基本要點
才華橫溢的Stoyan Stefanov,在他寫的由O’Reilly初版的新書《JavaScript Patterns》(JavaScript模式)中,我想要是為我們的讀者貢獻其摘要,那會是件很美妙的事情2012-01-01絕對經(jīng)典的滑輪新聞顯示(javascript+css)實現(xiàn)
這篇文章主要介紹了絕對經(jīng)典的滑輪新聞顯示(javascript+css)實現(xiàn),需要的朋友可以參考下2007-03-03