Удаление связанных объектов из массива ColdFusion - PullRequest
1 голос
/ 22 февраля 2012

У меня есть массив корзин, в котором хранится информация о товарах в корзине. Некоторые товары, которые будут добавлены, будут иметь специальную скидку, если они будут приобретены с «основным товаром».

Если кто-то добавляет элемент, с которым связаны специальные предложения, я задаю ключ в структуре элемента под названием mainitem со значением yes, все последующие элементы специального предложения, связанные с основным элементом, имеют ключ mainitem установлен как no и имеет другой ключ с именем mainitemid (это mainitem uid).

Если кто-то удаляет основной элемент, мне нужно убедиться, что также удалены все связанные элементы специального предложения. Это то, с чем у меня проблемы, я не могу понять, как их всех найти.

Я использую form.itemID для указания идентификатора удаляемого продукта. Мне нужно убедиться, что удаляемый элемент является основным; если это так, переберите оставшуюся часть корзины и найдите любой элемент с 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 ]

1 голос
/ 23 февраля 2012

Решение для конкретной проблемы ОП

Пересмотрен, чтобы предложить более полное решение

<!--- 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 немного прост и не обращает на это внимания, поэтому при удалении элемента 2 массива из 5 элементов массив становится длиной 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, поэтому некоторые методы, работающие с одним, не работают с другим.

0 голосов
/ 22 февраля 2012

Я не вижу способа сделать это за один цикл, поскольку я рассматриваю это как двухэтапный процесс.Сначала вы должны увидеть, является ли идентификатор элемента, который вы удалили, основным, а затем вернуться назад через массив и удалить остальные связанные элементы.

При необходимости добавьте 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>
0 голосов
/ 22 февраля 2012
<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>

Это, конечно, не проверено, и вам, возможно, придется поработать с ним, чтобы ввести ваши точные имена переменных, но я думаю, что это поможет вам.Дайте мне знать, если я неправильно понял вопрос.

...