2017-03-28 82 views
-1

我想在不更改原始數組的情況下過濾數組。你可以看到我在filterChange函數中做的第一件事是從原始數組拼接。原始數組仍然最終改變,我不明白爲什麼。保持原始數組的同時保持原始數組的Javascript過濾器深陣列

var MenuDisplayModule = (function ($, window, document, Handlebars) { 

    var module = {}; 
    module.menuItems = []; 
    module.init = function() { 
     console.info('BreadcrumbDisplayModule Init'); 

    }; 
    module.template = function (array) { 
     module.menuItems = array; 
     var filteredMenuItems = array.slice(0); 
     _template(filteredMenuItems); 
    } 
    module.filterChange = function (filterText) { 

     var filteredMenuItems = module.menuItems.slice(0); 

     filteredMenuItems.forEach(function (item, index) { 
      var filteredItems = item.MenuItems.filter(function (el) { 
       return (el.MenuText.includes(filterText)); 
      }); 
      filteredMenuItems[index].MenuItems = filteredItems; 
     }) 
     _template(filteredMenuItems); 
    } 
    function _template(filteredMenuItems) { 
     var menu_items_source = $("#menu-items-template").html(); 
     var menu_items_template = Handlebars.compile(menu_items_source); 
     $("#menu-items-placeholder").empty().html(menu_items_template({ menuItems: filteredMenuItems })); 
    } 
    return module; 
}(window.jQuery, window, document, window.Handlebars)); 
+2

您能否提供一些代碼,說明您在何處/如何使用此模塊進行測試? –

+1

沒有關於數組實際內容的更多信息,對象的結構很難做出決定性的結論,但「slice」只執行淺拷貝,因此數組內的對象將成爲任何副本中的相同對象該陣列。例如,如果你在這些數組中嵌入了DOM元素,你將永遠不會擁有這些元素的副本。如果他們被放置在你的文檔中,他們將實際移動*而不是重複。在這些DOM元素上使用'clone'方法。 – trincot

回答

0

如果你要過濾的陣列,並創建一個新的包含過濾內容,並留下舊不變,我建議

newArray = oldArray.filter(function(item) { return item.wantThis === true; }) 

現在你有newArray只由具有財產的對象

item.wantThis === true 

在你比如你正在使用slice()這在我的經驗,看起來非常像splice()(這將可能變異的陣列)。

我建議你只要堅持使用filter()

但是你爲什麼要做這麼多的切片副本?

如果您在接收的數組中發佈了一個對象的示例,這將有所幫助。

形態看你的例子似乎filteredItems是一個私人VAR以前的foreach循環,如果你改變你的代碼的積極參與來....

module.filterChange = function (filterText) { 

    var filteredMenuItems = module.menuItems.slice(0); 

    var filteredItems; // declare the var outside of the .forEach 

     filteredMenuItems.forEach(function (item, index) { 
      filteredItems = item.MenuItems.filter(function (el) { 
      return (el.MenuText.includes(filterText)); 
     }); 
     filteredMenuItems[index].MenuItems = filteredItems; 
    }) 
    _template(filteredMenuItems); 
} 

它可能會奏效。

您filteredItems的效果..

filteredMenuItems.forEach(function(item) { 
    item.MenuItems = item.MenuItems 
          .filter(function(el) { return (el.MenuText.includes(filterText)); }); 
    }) 

所以你item.MenuItems將獲得與每個過濾器更小。

+1

如果你看看OP代碼的一半,你會發現他們已經使用了這個功能。這不是問題。 – trincot

+1

來自MDN:slice()方法將數組的一部分的淺表副本返回到從開始到結束(未包含結束)中選擇的新數組對象中。原始數組不會被修改。除非我不明白這是什麼意思,切片不會改變陣列的名稱。 – Cadean

0

所以看來我不明白拼接。具體來說就是淺的方面吧。因爲我想過濾陣列的子陣列,所以我試圖複製,結果沒有得到實際的副本。

而不是複製數組我創建一個新的數組並將過濾器的結果推送給它。用它從原始數組中取消未過濾的屬性。

module.filterChange = function (filterText) { 
    var filteredMenuItems = []; 
    module.menuItems.forEach(function (item, index) { 
     var filteredItems = item.MenuItems.filter(function (el) { 
      return (el.MenuText.includes(filterText)); 
     }); 
     filteredMenuItems.push({ 
      HeaderText: item.HeaderText, 
      ID: item.ID, 
      MenuItems: filteredItems 
     }) 
    }) 
    _templateOnChange(filteredMenuItems); 
} 
相關問題