从阵列ColdFusion中删除关联的对象

时间:2012-02-22 19:25:26

标签: coldfusion

我有一个购物车阵列,其中包含购物车中商品的商品信息。如果与“主要项目”一起购买,某些添加的产品将享受特别折扣。

如果有人添加了与其相关联的特殊商品的商品,我会在名为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>

我是否需要创建两个循环或者我可以使用一个循环?我不确定我的条件陈述。

3 个答案:

答案 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>