<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

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

        來源:懂視網 責編:小采 時間:2020-11-27 20:31:39
        文檔

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

        JavaScript中對大量數據的多重過濾:所有代碼使用 ES2015 語法,需要 ES5 語法的可以用 Babel - Try it out 或者 TypeScript Playground 翻譯。問題提出今天有朋友問我一個問題,前端通過 Ajax 從后端取得了大量的數據,需要根據一些條件過濾,過濾的方法是這樣的:class Filter {
        推薦度:
        導讀JavaScript中對大量數據的多重過濾:所有代碼使用 ES2015 語法,需要 ES5 語法的可以用 Babel - Try it out 或者 TypeScript Playground 翻譯。問題提出今天有朋友問我一個問題,前端通過 Ajax 從后端取得了大量的數據,需要根據一些條件過濾,過濾的方法是這樣的:class Filter {
        所有代碼使用 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 個中間結果。而延遲處理只會進行一次大循環,沒有中間結果產生。

        892670031-581ee02140c15_articlex.png

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

        自己實現延遲處理

        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 之類的工具,很容易就處理出來了。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

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

        JavaScript中對大量數據的多重過濾:所有代碼使用 ES2015 語法,需要 ES5 語法的可以用 Babel - Try it out 或者 TypeScript Playground 翻譯。問題提出今天有朋友問我一個問題,前端通過 Ajax 從后端取得了大量的數據,需要根據一些條件過濾,過濾的方法是這樣的:class Filter {
        推薦度:
        標簽: 批量 數據 js
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费A级毛片在线播放不收费| 免费在线观看视频网站| 成年大片免费视频| 亚洲人成电影亚洲人成9999网| 日本视频免费观看| 全部免费国产潢色一级| 亚洲综合一区二区三区四区五区| 午夜网站在线观看免费完整高清观看| 亚洲综合色成在线播放| 日韩毛片免费一二三| 亚洲AV无码乱码在线观看性色扶| 亚洲日韩乱码中文字幕| 国产va免费精品观看精品| 亚洲日产2021三区在线| 午夜不卡久久精品无码免费| 亚洲av之男人的天堂网站| A片在线免费观看| 国产亚洲一区二区在线观看| 精品多毛少妇人妻AV免费久久| 亚洲精品线路一在线观看 | 亚洲女久久久噜噜噜熟女| 无人视频免费观看免费视频 | 久久国产乱子精品免费女| 亚洲制服丝袜一区二区三区| 黄色网址在线免费| 亚洲尹人九九大色香蕉网站| 3d成人免费动漫在线观看| 91亚洲精品自在在线观看| 噼里啪啦电影在线观看免费高清| 亚洲五月综合网色九月色| 精品国产免费一区二区| 高潮毛片无遮挡高清免费视频| 久久精品国产亚洲精品| 中国国语毛片免费观看视频| 亚洲国产成人久久精品动漫| 在线看片韩国免费人成视频| 亚洲精品亚洲人成在线| 久久久无码精品亚洲日韩软件 | 国产国产人免费人成成免视频| 国产成人无码综合亚洲日韩| 人与禽交免费网站视频|