簡體   English   中英

javascript(ES6):比“for loops”更有效的方法嗎?

[英]javascript (ES6): any more efficient way than “for loops”?

這不是重復的。 請看下面的評論!

有人知道比ES6中的循環更有效的解決方案嗎?

我寫了以下內容,但缺乏性能。 任何改進的想法? 非常感謝。

基本上我有一個關於汽車的對象和一個關於用戶偏好的數組。 預期的行為是將所有相關的汽車名稱推送到一個數組中。

用戶可以提供任何數量的偏好。 如果首選項中提到了所有規格,則只應推送汽車名稱。 因此,一些偏好將是“剩飯”。

出於這個原因,在下面的例子中,本田出現了,但不是寶馬,這是預期的(但非常緩慢的行為)。

 // Car objects const cars = [{ name: "Honda", category: "eco", specs: { 0: "green", 1: "fast", 2: "automatic" } }, { name: "BMW", category: "sport", specs: { 0: "blue", 1: "fast", 2: "automatic" } } ] // User preferences const preferences = ["green", "fast", "4x4", "automatic", "panorama"] // function to get length/amount of car specifications function objsize(Myobj) { var osize = 0, key; for (key in Myobj) { if (Myobj.hasOwnProperty(key)) osize++; } return Object(osize); }; //function to check if ALL specifications are included in the user preferences function checkSpecs(spec_item) { return preferences.includes(spec_item) } // main function function filter_func() { //final results let matched_cars = [] for (i = 0; i < objsize(cars); i++) { let specs_collector = [] for (j = 0; j < objsize(cars[i].specs); j++) { specs_collector.push(cars[i].specs[j]) } if (specs_collector.every(checkSpecs) === true) { matched_cars.push(cars[i].name) specs_collector = [] } } console.log(matched_cars) } filter_func() 

您無法真正避免查看每輛車,並且您無法避免查看車內的每個規格,因為您想要測試每一輛車。 您可以通過使用Set避免每次循環首選項。

所以這可能會或者可能不會更快,但它簡單,更容易理解,因為代碼幾乎像英語一樣:過濾汽車,其中每個規格都在首選項中:

 // Car objects const cars = [{ name: "Honda", category: "eco", specs: ["green", "fast","automatic"] }, { name: "BMW", category: "sport", specs: ["blue", "fast","automatic"] } ] const preferences = new Set(["green", "fast", "4x4", "automatic", "panorama"]) let filtered = cars.filter(car => car.specs.every(spec => preferences.has(spec))) console.log(filtered) 

- 編輯 -

使用OP中的數據:

 const array_intersect = (a, b) => a.filter( i => (b.indexOf(i) >= 0) ) const a_contains_b = (a, b) => array_intersect(a, b).length == b.length var cars = [{ name: "Honda", category: "eco", specs: ["green", "fast", "automatic"] }, { name: "BMW", category: "sport", specs: ["blue", "fast", "automatic"] } ] const preferences = ["green", "fast", "4x4", "automatic", "panorama"] let filtered = cars.filter(car => a_contains_b(preferences, car.specs)) console.log(filtered); 

沒有辦法逃脫至少一個循環。 你總是需要遍歷所有的汽車,無論是使用for ...還是使用另一個類似array.filter()的結構。 但還有另一種方法可以獲得性能。 您可以使用位掩碼。 這將需要改變汽車對象的數據結構,以便每輛汽車已經包含與其規格相對應的位掩碼,並且當用戶選擇所需的規格時,同樣應該添加規范代碼。 (但是,我懷疑這可能太麻煩了,收獲不多。)

 // Let's pretend there are preset binary digits corresponding // to each one of the available preferences: // // "blue" => 1 // "green" => 2 // "red" => 4 // "fast" => 8 // "slow" => 16 // "automatic" => 32 // "4x4" => 64 // "panorama" => 128 // // You would encode this into the data before processing var cars = [{ name: "Honda", category: "eco", specs: ["green", "fast", "automatic"], bin_specs: 42 // 2 + 8 + 32 }, { name: "BMW", category: "sport", specs: ["blue", "fast", "automatic"], bin_specs: 41 // 1 + 8 + 32 } ] const preferences = ["green", "fast", "4x4", "automatic", "panorama"] const bin_preferences = 234 // 2 + 8 + 64 + 32 + 128] let filtered = cars.filter(car => (car.bin_specs & bin_preferences) === car.bin_specs) console.log(filtered); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM