我有一个购物车阵列,其中包含购物车中商品的商品信息。如果与“主要项目”一起购买,某些添加的产品将享受特别折扣。
如果有人添加了与其相关联的特殊商品的商品,我会在名为mainitem
的商品结构中设置一个值为yes
的商品,所有后续特价商品都与主商品相关联item将密钥mainitem
设置为no
,并使用另一个名为mainitemid
的密钥(这是mainitem
uid)。
如果有人删除了主题,我需要确保删除任何相关的特价商品。这就是我遇到的麻烦,无法找到如何找到它们。
我正在使用form.itemID
来提供要删除的产品的商品ID。我需要确保被删除的项目是一个主要项目;如果是这样,请循环浏览购物车的其余部分,找到mainitemid
等于form.itemid
的任何商品并将其删除,然后删除mainitem
。
mainitem
定义为session.mycart[i].mainitem
maintitenid定义为session.mycart[i].mainitemid
<cfloop index="i" from="1" to="#arrayLen(session.mycart)#">
</cfloop>
我是否需要创建两个循环或者我可以使用一个循环?我不确定我的条件陈述。
答案 0 :(得分:1)
OP特定问题的解决方案
修订以提供更完整的解决方案
<!--- First of all, will need to go 1 to ArrayLen() to find the main item id. Doesn't matter what order you go here, but main items should be inserted before children so may as well start at the bottom --->
<cfloop index="i" from="1" to="#ArrayLen(session.mycart)#">
<!--- Is this the main item? --->
<cfif session.mycart[i].id EQ form.itemID>
<!--- It's found the item, is it a main item? We've found the item so entering here to break the loop --->
<cfif session.mycart[i].mainitem>
<!--- Go from ArrayLen() to 1, as if you go 1 to ArrayLen() when deleting you confuse Coldfusion --->
<cfloop index="j" from="#ArrayLen(session.mycart)#" to="1" step="-1">
<cfif session.mycart[j].id EQ form.itemID OR session.mycart[j].mainitemid EQ form.itemID>
<cfset ArrayDeleteAt(session.mycart,j)>
</cfif>
</cfloop>
</cfif>
<!--- This loop is done, so break out --->
<cfbreak>
</cfif>
</cfloop>
在你的帖子中,你声明你正在从索引1循环到索引ArrayLen(...)。如果你要从数组中删除项目,Coldfusion有点简单,并没有真正注意,因此当你删除5元素数组的元素2时,数组变为4个元素长(因为你删除了一个)和索引3的元素现在是索引2,因此它被遗漏了。
解决这个问题的方法是从最后开始并向后工作。只要你一次删除最多1条记录,那么这是完全有效的,因为它将继续减少它当前正在检查的索引,直到你降到1,这将是第一个元素。
这样你可以通过元素5,4,3,2,删除元素2,然后它将检查索引1,它现在仍然是与启动循环时相同的项目,因此没有跳过是经历。
关于如何处理此问题的一些模糊
我误读了这个问题,或者在编写本文时对其进行了编辑,但以下内容适用于此,请将其留在此处
您是否考虑过将特别优惠项目作为主要项目的子项,因为它将整个商品封装在一起并删除父项删除该子项。我有一个类似的问题,其中项目有与它们相关的选项,并且为了允许观察层次结构,我决定创建一个结合参考数组的树。正如展示原理的一个粗略的例子,看看这个
<cfscript>
// Create a main item structure
stcMainItem = {
id = CreateUUID(),
somekey = somevalue,
someotherkey = someothervalue,
cost = 123
};
// Create some child item structures, special offers for ex
stcSpecialOfferItem1 = {
id = CreateUUID(),
parent = stcMainItem.id,
cost = 45
};
stcSpecialOfferItem2 = {
id = CreateUUID(),
parent = stcMainItem.id,
cost = 45
};
// Each is added to a reference array
arrItemReference = [];
arrItemRefernce.add(stcMainItem);
arrItemRefernce.add(stcSpecialOfferItem1);
arrItemRefernce.add(stcSpecialOfferItem2);
// Now you decide to delete the main item and direct parents
strIDToDelete = stcMainItem.id;
for (i=ArrayLen(arrItemReference);i>=1;i--) {
if (
arrItemReference[i].id == strIDToDelete
||
arrItemReference[i].parent == strIDToDelete
) {
ArrayDeleteAt(arrItemReference,i);
}
}
</cfscript>
在我的实际代码中,我通过创建一个Item.cfc方法来处理上面的内容并将树级联为删除孙子等,但原理是合理的。基本上你有一些方法允许项目作为平面数组以及父母,子女和兄弟姐妹的层次结构公开。
信息点
顺便说一下,当两者略有不同时,你会不断地交换“数组”和“结构”,这与PHP之类的语言不同,其中数组用于引用这两个术语。数组包含具有从1到n的数字索引的值,而结构是包含与任意键相关的值的对象。之所以存在差异,是因为它们不会构建相同的基础java对象,因此一些处理一个的方法在另一个上不起作用。
答案 1 :(得分:0)
<cfloop index="i" from="1" to="#arrayLen(session.mycart)#">
<cfif session.mycart[i].mainitem eq "no" AND session.mycart[i].mainitemid EQ form.itemid>
<cfset arrayDeleteAt(session.myCart,i) />
<cfset i = i - 1 /><!--- this is necessary to keep you from running out of the end of the loop --->
</cfif>
</cfloop>
这当然没有经过测试,您可能需要使用它来准确输入您的变量名称,但我认为它应该可以帮到您。如果我误解了这个问题,请告诉我。
答案 2 :(得分:0)
我没有看到在一个循环中执行此操作的方法,因为我将其视为两步过程。首先,您必须查看您删除的项目ID是否为主项目,然后返回数组并删除其余相关项目。
根据需要添加StructKeyExists()。
<!--- Find Main Item --->
<cfset isMainItem = false />
<cfloop from='1' to='#ArrayLen( Session.MyCart )#' index='item'>
<cfif Session.MyCart[ item ].ItemID EQ Form.ItemID AND Session.MyCart[ item ].MainItem EQ 'Yes'>
<cfset isMainItem = true />
<cfbreak />
</cfif>
</cfloop>
<cfif isMainItem>
<!--- Clean up special offer items --->
<cfloop from='1' to='#ArrayLen( Session.MyCart )#' index='item'>
<cfif Session.MyCart[ item ].MainItemID EQ Form.ItemID AND Session.MyCart[ item ].MainItem EQ 'No'>
<cfset ArrayDeleteAt( Sesion.MyCart, Item ) />
<cfset item-- />
</cfif>
</cfloop>
</cfif>