Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Sort values of structure with arrays

New Here ,
Sep 28, 2010 Sep 28, 2010

Hi

For a shopping cart I'm using a structure with arrays to store the items in the cart. I tried to use StructSort but did not work...

This is how I store the items in the cart:

<cfscript>
            if (not(isdefined("session.cart"))) {                // Check to make sure that the Shopping cart structure exists.
                session.cart = structnew();

            // The item structure we are going to use to store the items in the cart
            // is going to have four parts...
            //         1.  The item id
            //         2.  The item name
            //         3.  The price per unit
            //         4.  The quantity

            tempvalue = listtoarray('#attributes.id#,#attributes.name#,#attributes.price#,#attributes.quantity#');

            // if the item is not yet in the cart, simply add it to the cart
            if (not(structKeyExists(session.cart, attributes.name))) {
                StructInsert(session.cart,attributes.name,tempvalue);
            }

            // if the item is already in the cart, update the item quantity
            else {
                tempvalue[4]=session.cart[attributes.name][4]+attributes.quantity;
                StructUpdate(session.cart,attributes.name,tempvalue);
            }           
</cfscript>

Any help will be appreciated.

Thank you.

TJ

1.1K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 28, 2010 Sep 28, 2010

Not that this answers your question, but don't you want an array of structs, not a struct of arrays?

Each element of the array would be an item in the cart, which itself would be a struct keyed on those parts you list:

Item 1:

ID: OCE1

Name: ocelot

Price: £5

Quantity: 3

Item 2:

ID: PAN6

Name: pangolin

Price: £10

Quantity: 6

etc

What is it you're trying to achieve by sorting this?  What's the ordering you are after?

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 28, 2010 Sep 28, 2010

I don't mind to use an array of structs...is there many changes involved?

To display the cart I simply use a loop:

<cfloop collection="#session.cart#" item="i">

#session.cart[2]# #session.cart[3]# #session.cart[4]#<br>

</cfloop>

To answer your questions:

When I display the shopping cart I'd like to show the items ordered by name or by price as at the moment they don't display in any order. It displays the items in a random order. At first I thought it was in the order that you add them in the cart but that's not the case.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 28, 2010 Sep 28, 2010

To loop over an array one has two options:

<cfloop index="i" from="1" to="#arrayLen(a)#">

Or:

<cfloop index="someVar" array="#a#">

Personally I use the former because I think the implementation of array-looping with <cfloop> is cocked-up as it's not the index that gets put into "someVar", it's the array element itself.  So by way of pedantic protest, I don't use that syntax.

But anyway...

The reason why your struct is unordered is because structs are - innately, and by definition - unordered.  If you want an ordered data structure, you use an array.

However what you are wanting to do is to sort your array by a subkey value of the structs the array contains.  If you want to do that, you will need to roll your own sorting solution.

Personally I'd stick with using an array and just use its intrinsic ordering (the order in which items are added to it).  However if you wanted to sort on one of the inner struct keys, you could maintain a separate struct keyed on the value you wish to sort on, containing a reference to the array element in the original array.  Then you could extract a structKeyArray() from that, and use arraySort() to order those index keys in whichever order you like.

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 28, 2010 Sep 28, 2010

I'll start looking into doing an array of structs...in the mean time perhaps someone else out there knows how to sort the values of an structure of arrays.

Thanks

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 28, 2010 Sep 28, 2010

What is the key your using for the outer struct?  I am finding it hard to get my brain around how you are implementing this cart as a struct of arrays.

What's some sample data?

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 28, 2010 Sep 28, 2010

Hi Adam

This is inherited old code that I'm trying to update...

Anyway to answer your question the key for the outer struct is the item's name. Here is a screen-shot of some sample data using cfdump. It's ironic that cfdump successfully sorts the item's name alphabetically...

cfdump_shoppingCart.jpg

I hope this extra information helps.

TJ

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Sep 28, 2010 Sep 28, 2010
LATEST

One doesn't actually sort the structure. I.E. nothing is done to the data in memory.

The structSort() function returns an array of the structKeys in sorted order.

One then loops over this array, uses the key name in each array element in turn to access the data from the original structure variable.

<cfset aStruct = [c=1,a=2,z=3,m=4]>

<cfset sortedAry = structSort(aStruct)>

<cfloop from="1" to="#arrayLen(sortedAry)#" index="i">

     <cfoutput>Key: #sortedAry# Value: #aStruct[sortedAry]#</cfoutput><br/>

</cfloop>

Untested code, but that is the idea.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources