我有两个数组。如果用户添加了产品,我们会将其放入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;
}
}
似乎应该有更好的方法来完成这项任务。
是否有更有效的方法从数组中删除单个项目(总是一个整数)?
答案 0 :(得分:3)
您可以创建两个列表对象而不是整数数组,并使用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编码的哈希(或map,或者依赖于语言的assoc数组)而不是列表,但这绝对是一种更快的方式删除。
答案 1 :(得分:1)
一个不同的想法是删除一个项目超级快,只是维护一个项目列表,并在每个项目上有一个属性,以确定它是否被删除。
然后要移除一个项目,只需设置它的属性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
});
答案 2 :(得分:1)
使用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;
}
答案 3 :(得分:1)
首先,通常会误认为调用函数比编写10行代码更有效。我们大多数人都不认为函数实际上是做什么以及函数中有多少行。例如: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"
}
答案 4 :(得分:0)
可能会弄错,但不是你的代码只是和
一样ProductArray.splice(ProductArray.indexOf(ItemID),1);
(没有经过测试和编写,但据我所知,这应该可以正常工作,但如果你有多个带有ItemID的项目它将不起作用)
答案 5 :(得分:0)
没有。这样的操作必须花费线性时间来找到要移除的元素(假设项目没有以任何方式排序)并向后移动后续元素。正如其他答案所暗示的那样,可以清理代码。
答案 6 :(得分:0)
为什么不使用对象,其中键是产品ID#s,并且值包含您想要的任何元数据(例如,当删除发生时,在哪个网页上等;它甚至可以是任意的)。
var added = {432215: {...}, 432676: {...}};
var removed = {432215: {...}};
如果您愿意修改一些内容,那将是最有效的方式。然而,你的问题“什么是最有效的方式......”并不合理,因为用户不太可能在他的购物车顶部有超过100件物品。即使你有一个O(N ^ 2)算法,你也不会看到问题,直到1000项。所以只需使用最容易编码的方法。
请注意,此系统的设计存在一个可能的缺陷:客户删除项目并稍后将其添加回来是合理的。根据您所追踪的内容,您可能需要特殊情况。
答案 7 :(得分:0)
我会这样做的:
var itemId = 6;
var products = [1,3,5,6,7];
var removedProducts = new Array();
removedProducts.push(
products.splice(products.indexOf(itemId), 1)
);
答案 8 :(得分:0)
排序可能出乎意料地得到了优化。 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)
);