Javascript在保留原始数组的同时过滤数组中的深层数组
我想过滤一个数组,而不更改从中切片的原始数组。您可以看到,我在filterChange函数中做的第一件事是从原始阵列拼接。原来的阵列仍然会改变,我不明白为什么Javascript在保留原始数组的同时过滤数组中的深层数组,javascript,arrays,filter,handlebars.js,Javascript,Arrays,Filter,Handlebars.js,我想过滤一个数组,而不更改从中切片的原始数组。您可以看到,我在filterChange函数中做的第一件事是从原始阵列拼接。原来的阵列仍然会改变,我不明白为什么 var MenuDisplayModule = (function ($, window, document, Handlebars) { var module = {}; module.menuItems = []; module.init = function () { console.inf
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));
如果您想过滤数组并创建一个包含过滤内容的新数组,而保留旧数组不变,我建议
newArray = oldArray.filter(function(item) { return item.wantThis === true; })
现在您有了newArray,它只包含那些具有属性的对象
item.wantThis === true
在您的示例中,您使用的是slice()
,根据我的经验,它看起来非常像splice()
(它可以改变数组)
我建议您只需坚持使用filter()
但是你为什么要做这么多的切片拷贝呢
如果您在收到的数组中发布一个对象的示例,这会有所帮助
表单查看您的示例,如果您将代码的活动部分更改为…,则filteredItems似乎是前一个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将随着每个过滤器而变小。因此,我似乎不理解拼接。特别是它的肤浅方面。因为我想在我试图复制的数组的子数组上进行过滤,所以最终没有得到实际的副本 我不是复制数组,而是创建一个新数组并将过滤器的结果推送到它。从原始数组中获取未筛选的属性
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);
}
如果你查看OP代码的一半,你会发现他们已经在使用这个函数了。这不是问题所在。From MDN:slice()方法将数组部分的浅层副本返回到从开始到结束(不包括结束)选择的新数组对象中。原始数组将不会被修改。除非我不明白这意味着什么,否则slice不会变异你调用它的数组。你能提供一些代码,说明你在哪里/如何使用这个模块进行测试吗?没有更多关于数组的实际内容、对象的结构的信息,很难得出结论,但是
slice
只执行一个浅拷贝,因此,数组中的对象将与该数组的任何副本中的对象相同。例如,如果这些数组中嵌入了DOM元素,则永远不会有这些元素的副本。如果将它们放置在文档中,它们将实际移动,而不是复制。对这些DOM元素使用clone
方法。