[英]Most efficient way to remove an item from array?
我有两个 arrays。如果用户添加了一个产品,我们将其放入 ProductArray。 如果他们删除了该产品,我们将其添加到 ProductArrayRemove 数组并将其从产品数组中删除。 (我们需要知道已添加的产品以及已删除的产品。这需要冗余。)
ProductArray = JSON.parse(ProductArray);
ProductArrayRemove = JSON.parse(ProductArrayRemove);
当我将项目添加到数组时,我只是这样做:
ProductArray.push(ItemID);
ProductArrayRemove.push(ItemID);
但是当我删除它时,我必须这样做:
var len = ProductArray.length;
for (i = 0; i < len; i++) {
ProductID = ProductArray[i];
if (ProductID == ItemID) {
ProductArray.splice(i,1);
break;
}
}
似乎应该有更好的方法来完成这项任务。
是否有更有效的方法从数组中删除单个项目(始终是整数)?
您可以创建两个列表对象而不是整数数组,并使用delete
删除项目:
// removing an item
function RemoveProduct(ItemID) {
delete ProductsAdded[ItemID];
ProductsRemoved[ItemID] = ItemID;
}
// adding an item
function AddProduct(ItemID) {
delete ProductsRemoved[ItemID];
ProductsAdded[ItemID] = ItemID;
}
现在,这需要在服务器端进行一些额外的修改,因为它应该发送json编码的散列(或映射,或者依赖于语言的assoc数组)而不是列表,但这绝对是一种更快的删除方法。
删除项目的一个不同的想法是只保留一个项目列表,并在每个项目上具有一个属性,以确定它是否被删除。
然后删除一个项目,你只需要设置它的属性obj.removed = true
。
再次添加它,您只需更改该属性的值。
要仅迭代添加的项,您只需跳过具有.removed == true
属性的项。 要仅迭代已删除的项目,您可以反过来。 这里有几个迭代器:
ProductArray.iterateAdded = function(fn) {
for (var i = 0; i < this.length; i++) {
if (!this[i].removed) {
if (fn.call(this, i, this[i]) === false) {
return;
}
}
}
}
ProductArray.iterateRemoved = function(fn) {
for (var i = 0; i < this.length; i++) {
if (this[i].removed) {
if (fn.call(this, i, this[i]) === false) {
return;
}
}
}
}
ProductArray.getSubLength = function(removed) {
var cnt = 0;
for (var i = 0; i < this.length; i++) {
if (removed == this[i].removed) {
++cnt;
}
}
return(cnt);
}
而且,你会像这样使用它们:
ProductArray.iterateAdded(function(i, val) {
// this is the array
// i is the index we are iterating
// val is the array element we are iterating this[i]
// put code here
});
使用Array方法indexOf-值得你需要额外的代码来向旧的和营养不良的浏览器解释它,以便在像你这样的代码中使用它。
var i= ProductArray.indexOf(ProductID);
if(i> -1) ProductArray.splice(i, 1);
//这个垫片大约平均:
if(!Array.prototype.indexOf) Array.prototype.indexOf= function(what, i){
if(!i || typeof i!= 'number') i= 0;
var L= this.length;
while(i< L){
if(this[i]=== what) return i;
++i;
}
return -1;
}
首先,通常会误认为调用函数比编写10行代码更有效。 我们大多数人都不认为函数实际上是做什么以及函数中有多少行。 例如: indexOf
不使用循环或其他变量,则无法实现indexOf
。
在你的情况下,你使用push
添加一个元素,它实际上在数组的末尾附加一个元素。 所以很简单,再向阵列添加一个内存位置。 但是当你删除一个元素时,你将它从数组中的任何索引中删除。 所以涉及的步骤是
显然需要循环,并且使用循环不会降低效率。 我的建议是避免使用splice
(因为你已经开始循环)并仅使用你的循环删除元素 - 做一些如下所示的事情
var len = ProductArray.length;
for (i = 0; i < len; i++) {
ProductID = ProductArray[i];
if (ProductID == ItemID && i != len-1) {
ProductArray[i] = ProductArray[i+1];
ProductArray[i+1] = ItemID;
}else if(i == len-1){
ProductArray.length = i;
}
}
您可以通过将其添加到protoype使其成为数组的函数
Array.prototype.removeItem = function (itemID){
// put the code here replacing "ProductArray" with "this"
}
Array.prototype.filter()
应该可以解决问题。 参考
Array.filter()
遍历每个数组元素(本例为product
)并根据您的需要返回一个新的修改后的数组(本例返回一个没有删除产品的数组)
它看起来像这样:
ProductArray = ProductArray.filter(function(product) {
return product !== ItemID
})
product
是 ProductArray 中的每个数组元素。
您甚至可以使用箭头 function使其更小,这几乎与function()
相同,但更紧凑和有限。
ProductArray = ProductArray.filter(product => product !== ItemID)
现在 ProductArray 没有删除的产品,它是一个单线解决方案
可能会弄错,但不是你的代码只是做同样的事情
ProductArray.splice(ProductArray.indexOf(ItemID),1);
(没有经过测试和编写,但据我所知,这应该可以正常工作,但如果你有多个ItemID项,它将不起作用)
不需要。这样的操作必须花费线性时间来找到要移除的元素(假设项目没有以任何方式排序)并向后移动后续元素。 可以像其他答案所建议的那样清理代码。
为什么不使用对象,其中键是产品ID#s,并且值包含您想要的任何元数据(例如,当删除发生时,在什么网页上等;它甚至可以是任意的)。
var added = {432215: {...}, 432676: {...}};
var removed = {432215: {...}};
如果你愿意修改一些东西,这就是你要求的最有效的方法。 然而,你的问题“什么是最有效的方式......”并不合理,因为用户不太可能在他的购物车顶部有超过100件物品。 即使你有一个O(N ^ 2)算法,你也不会看到问题,直到1000项。 所以只需使用最容易编码的方法。
请注意,该系统的设计存在一个可能的缺陷:客户移除物品并在以后添加物品是合理的。 根据您的跟踪记录,您可能需要特殊情况。
我会这样做的:
var itemId = 6;
var products = [1,3,5,6,7];
var removedProducts = new Array();
removedProducts.push(
products.splice(products.indexOf(itemId), 1)
);
在大多数浏览器中,Sort可能出乎意料地得到了很好 Pop通常也非常快,因为堆栈的概念始于汇编。 能够定义排序函数真的很强大。 大多数情况下,虽然我得到的印象是你喜欢它,但我认为这更容易使用。
Array.prototype.numFindPop = function(id){
this.sort(
function(a,b){
if(a === id){ return -1; }//keeps moving id to the right when found
}
);
return this.pop();
}
所以在你的情况下:
//remove
ProductArrayRemove.push(
ProductArray.numFindPop(35)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.