中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中如何對大量數據的多重過濾

發布時間:2021-11-16 17:30:19 來源:億速云 閱讀:133 作者:柒染 欄目:web開發

本篇文章為大家展示了JavaScript中如何對大量數據的多重過濾,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

所有代碼使用 ES2015 語法,需要 ES5 語法的可以用 Babel - Try it out 或者 TypeScript Playground  翻譯。

問題提出

今天有朋友問我一個問題,前端通過 Ajax 從后端取得了大量的數據,需要根據一些條件過濾,過濾的方法是這樣的:

class Filter {     filterA(s) {         let data = this.filterData || this.data;         this.filterData = data.filter(m => m.a === s);     }          filterB(s) {         let data = this.filterData || this.data;         this.filterData = data.filter(m => m.b === s);     } }

現在迷糊了,覺得這樣處理數據不對,但是又不知道該怎么處理。

發現問題

問題就在過濾上,這樣固然可以實現多重過濾(先調用 filterA() 再調用 filterB()  就可以實現),但是這個過濾是不可逆的。假如過濾過程是這樣:

f.filterA("a1"); f.filterB("b1"); f.filterA("a2");

本來是希望按 "a1" 和 "b1" 過濾了數據之后,再修改***個條件為 "a2",但結果卻成了空集。

解決問題

發現了問題,就針對性的解決。這個問題既然是因為過濾過程不可逆造成的,那每次都直接從 this.data 開始過濾,而不是從this.filterData  開始過濾,就能解決問題。如果要這樣做,就需要將選擇的過濾條件先記錄下來。

記錄過濾條件

用一個列表記錄過濾條件當然是可行的,但是注意對同一個條件的兩次過濾是互斥的,只能保留***一個,所以應該用 HashMap 更為合適。

class Filter {     constructor() {         this.filters = {};     }      set(key, filter) {         this.filters[key] = filter;     }      getFilters() {         return Object.keys(this.filters).map(key => this.filters[key]);     } }

這種情況下,像上面的過程表示為

f.set("A", m => m.a === "a1"); f.set("B", m => m.b === "b1"); f.set("A", m => m.a === "a1"); let filters = f.getFilters(); // length === 2;

上面第 3 句設置的 filter 覆蓋了第 1 句設置的那個。現在再用***取得的 filters 依次來過濾原數據  this.data,就能得到正確的結果。

有人會覺得 getFilters() 返回的列表不是按 set 的順序的——的確,這是 HashMap  的特點,無序。不過對于簡單條件的判斷,不管誰先誰后,結果是一樣的。但是對于一些復合條件判斷,就可能會有影響。

確實需要的話,可以通過 array 代替 map 來解決一下順序的問題,但這樣查找效率會降低(線性查找)。如果還想解決查找效率的問題,可以用 array  + map 來處理。這里就不多說了。

過濾

實際上在使用的時候,每次都 getFilter() 再用一個循環來處理確實比較慢。既然 data 都封裝成 Filter  中,可以考慮直接給一個filter() 方法來送貨過濾接口。

class Filter {     filter() {         let data = this.data;         for (let f of this.getFilters()) {             data = data.filter(f);         }         return data;     } }

不過這樣我覺得效率不太好,尤其是對大量數據的時候。不妨利用一下 lodash 的延遲處理過程。

利用 lodash 的延遲處理

filter() {     let chain = _(this.data);     for (let f of this.getFilters()) {         chain = chain.filter(f);     }     return chain.value(); }

lodash 在數據大于 200 的時候會啟用延遲處理過程,也就是說,它會處理成一個循環中依次調用每一個 filter,而不是對每一個 filter  進行一次循環。

延遲處理和非延遲處理通過下圖可以看出來區別。非延遲處理總共會進行 n(這里 n = 3) 次大循環,產生 n - 1  個中間結果。而延遲處理只會進行一次大循環,沒有中間結果產生。

JavaScript中如何對大量數據的多重過濾

不過說實在的,我不太喜歡為了一點小事多加載一個庫,所以干脆自己做個簡單的實現

自己實現延遲處理

filter() {     const filters = this.getFilters();     return data.filter(m => {         for (let f of filters) {             // 如果某個 filter 已經把它過濾掉了,也不用再用后面的 filter 來判斷了             if (!f(m)) {                 return false;             }         }         return true;     }); }

里面的 for 循環還可以用 Array.prototype.every 來簡化:

filter() {     const filters = this.getFilters();     return data.filter(m => {         return filters.every(f => f(m));     }); }

數據過濾其實并不是多復雜的事情,只要把思路理清楚,搞明白什么數據是需要保留的,什么數據是臨時(中間過程)的,什么數據是最終結果。利用  Array.prototype 中的相關方法,或者諸如 lodash 之類的工具,很容易就處理出來了。

上述內容就是JavaScript中如何對大量數據的多重過濾,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鄢陵县| 岳普湖县| 千阳县| 大竹县| 洛宁县| 滦平县| 铜山县| 江城| 子长县| 盐津县| 昭平县| 朝阳区| 保山市| 凤城市| 荥经县| 青铜峡市| 齐齐哈尔市| 中超| 象山县| 会同县| 修文县| 丰原市| 温泉县| 都安| 特克斯县| 抚宁县| 乌兰察布市| 宜黄县| 望城县| 射阳县| 锡林郭勒盟| 鄂尔多斯市| 建宁县| 定兴县| 开阳县| 宁远县| 林西县| 万盛区| 梨树县| 新津县| 漳浦县|