JavaScript中對大量資料的多重過濾

2021-09-23 07:00:23 字數 2361 閱讀 7730

所有**使用 es2015 語法,需要 es5 語法的可以用 babel - try it out 或者 typescript playground 翻譯。

問題提出

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

class filter  

filterb(s)  

}   現在迷糊了,覺得這樣處理資料不對,但是又不知道該怎麼處理。

發現問題

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

f.filtera("a1"); 

f.filterb("b1"); 

f.filtera("a2");  

本來是希望按 "a1" 和 "b1" 過濾了資料之後,再修改第乙個條件為 "a2",但結果卻成了空集。

解決問題

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

記錄過濾條件

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

class filter ; 

} set(key, filter)  

getfilters()  

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

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  

return data; 

} }  

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

利用 lodash 的延遲處理

filter()  

return chain.value(); 

}   lodash 在資料大於 200 的時候會啟用延遲處理過程,也就是說,它會處理成乙個迴圈中依次呼叫每乙個 filter,而不是對每乙個 filter 進行一次迴圈。

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

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

自己實現延遲處理

filter()  

} return

true; 

}); 

}   裡面的 for 迴圈還可以用 array.prototype.every 來簡化:

filter() ); 

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

JavaScript中對DOM操作

1 element,元素 2 attribute,屬性 3 text,文字 var node1 document.createelement div var node2 document.createtextnode hello world 返回當前文件中第乙個類名為 myclass 的元素 var...

javascript中對cookie的訪問查操作

瀏覽器向伺服器請求得到響應後 就與伺服器斷開連線 那麼伺服器該如何記住某個使用者呢 比如你登陸乙個 在站內跳轉到另乙個板塊後 伺服器怎麼確認你是剛才已經登陸的那個使用者呢 這裡就要用到cookie,乙個可以讓瀏覽器儲存使用者資訊的功能 cookie都是以 name value 這種成對形式儲存 所有...

No 009 在JavaScript中建立物件

6.混合使用建構函式和原型 以下所有內容僅用以記錄學習過程中的個人理解,如有錯誤歡迎指出 如下,直接建立乙個 18歲的女孩愛麗絲 物件 var person 該方法和字面量建立有著一樣的缺點 只能建立一次,創造多個的話會造成物件 冗餘。var person newobject 使用new objec...