2

I have a screen that needs to calculate prices based on two different parameters, primary (activity in example) and children (ticketType in example)

Previously this was done hackishly, so i decided the best option would be to store the prices in a JSON object populated at runtime, and based on clicks & change events

So i have this json format I formulated, please note you can change this as well, not set in stone

{
    "activities": [{
        "activitycode": "TK",
            "desc": "Tickets",
            "ticketTypes": [{
            "ticketcode": "G",
                "baseprice": 79
        }, {
            "ticketcode": "P",
                "baseprice": 109
        }]
    }, {
        "activitycode": "PK",
            "desc": "Parking",
            "ticketTypes": [{
            "ticketcode": "BK",
                "baseprice": 65
        }, {
            "ticketcode": "ESC-I",
                "baseprice": 40
        }]
    }], //end activities
    "handlingPercent": "0.03",
        "shipping": "15"
}

So, I tried traverse the JSON object for the correct price, like this

pricing.activities.activitycode['TK'].ticketTypes.ticketcode['G'].baseprice

but this doesnt work, because I havent specified which numerical node to go to yet before supplying my values

Once i did that, the following works

pricing.activities[0].ticketTypes[0].baseprice

But what i would like to accomplish is supplying string/text values, traverse parent nodes, then child nodes, and find the value

I suppose i could do an $.each iteration like this, but i wanted to know what the experts thought first, if this is indeed the best way to go about things

$.each(pricing.activities, function(arrayID, activityData) {    
if(activityData.activitycode=="TK")
    $.each(activityData.ticketTypes, function(ticketTypeID, typeData) {
        if(typeData.ticketcode=="G")
        alert(typeData.baseprice);
     });
});
Sushanth --
  • 55,259
  • 9
  • 66
  • 105
Jay Rizzi
  • 4,196
  • 5
  • 42
  • 71

2 Answers2

2

Have you tried $.grep()?

var test = $.grep(pricing.activities, function(e){ return e.activitycode == 'TK'; });
var test2 = $.grep(test[0].ticketTypes, function(e){ return e.ticketcode == "G";});

console.log(test2[0].baseprice);

Fiddle Here. jQuery API Documentation on $.grep() here

Example from this question

I wouldn't say it's better than $.each(), but it's another method, if you're into that sort of thing.

Community
  • 1
  • 1
Jason Nichols
  • 3,739
  • 3
  • 29
  • 49
2

Before talking about the code, let's talk about your JSON data.

First, I reformatted the data so I could follow the structure more easily:

{
    "activities": [
        {
            "activitycode": "TK",
            "desc": "Tickets",
            "ticketTypes": [
                { "ticketcode": "G", "baseprice": 79 },
                { "ticketcode": "P", "baseprice": 109 }
            ]
        },
        {
            "activitycode": "PK",
            "desc": "Parking",
            "ticketTypes": [
                { "ticketcode": "BK", "baseprice": 65 },
                { "ticketcode": "ESC-I", "baseprice": 40 }
            ]
        }
    ],
    "handlingPercent": "0.03",
    "shipping": "15"
}

Now that the structure is clear, here is the question: You have an activities array, and inside each of the elements of that array there is a ticketTypes array.

Does the order of items in these arrays matter? i.e. are they used to generate a display list that must be in the correct order?

And, how do you need to access these arrays? Do you primarily loop through them and do something with all the elements? Or do you use them to look up individual elements given a known activitycode and ticketcode - which is what the nested $.each loops at the end of your question end up doing?

Depending on the answers to these questions, you may be better served with a different kind of structure. Perhaps like this:

{
    "activities": {
        "TK": {
            "desc": "Tickets",
            "ticketTypes": {
                "G": { "baseprice": 79 },
                "P": { "baseprice": 109 }
            }
        },
        "PK": {
            "desc": "Parking",
            "ticketTypes": {
                "BK": { "baseprice": 65 },
                "ESC-I": { "baseprice": 40 }
            }
        }
    },
    "handlingPercent": "0.03",
    "shipping": "15"
}

Because now this code (I cleaned up the indentation here too):

$.each( pricing.activities, function( arrayID, activityData ) {
    if( activityData.activitycode=="TK" ) {
        $.each( activityData.ticketTypes, function( ticketTypeID, typeData ) {
            if( typeData.ticketcode=="G" )
                alert( typeData.baseprice );
         });
    }
});

can be replaced with:

alert( pricing.activities.TK.ticketTypes.G.baseprice );

and other similar code that you write will also be simpler. About the only thing you lose this way is the guarantee of ordering of the activities and ticketTypes: arrays have a guaranteed order, objects do not.

Michael Geary
  • 28,450
  • 9
  • 65
  • 75
  • I do not care about the order of items, and looping over them using a known activity and ticket code, but i really like how you showed me an alternative way of using json as an array, i might not use it in this case but eventually will probably rely on it, thank you, – Jay Rizzi Jun 06 '13 at 22:18