# Complex data structure organization in javascript?

Upon suggestion in the original question within stackoverflow, I'm bringing this question here.

Question Explained:

In a website that I built, I used complex multidimensional arrays to organize a multitude of information tables linked to events. I want to know if what I did was a viable efficient solution for the specific situation, or if something else would have made more sense, like using database tables or take an object oriented approach.

This is what I did:

I built a set of dropdown menus with javascript, The first list (category) determined what items where shown on the second list (service). If the user hovered over a category, the correlating services were displayed on the second list. If the user selected a service, a list of items in that service where shown in another part of the page(itemlist). Each item on the itemlist had unique values, prices, and 2 possible types, either check boxes or numerical entries.

Hopefully that will make the following array examples make sense. All you need to know further about these arrays is that they correlate to achieve the above result.

the below array is in image form for your convenience. Stack overflow refused to keep my formatting, making it unreadable.

There are over 20 copies of this (above) array item with different services.

ServiceArray[0][0]: [0]is the id to be assigned to the element. ['1]is text name to be outputted. ['2]is a variable name to be assigned. ['3]is a key value to be appended to each item so I can call on a correlating value in the first array set. ['4]is an example to be listed

the downsides to this approach are obvious. The complex array structures become difficult to manage. When working with the variables, I had to continuously recount each variable to find the array keys. In the end though, i was able to use this approach very dynamically for the drop-downs and service lists. Here are a few examples of the code used to dynamically generate the content with these arrays.

$(".dropdown-service > p").click(function () { var thisKey =$(this).data("key");
$("#ServiceOutput").text($(this).text());
$(".layer4").append('<div class="ChoiceWrap">'); for (var i = 0; i < ServiceArray[Category][thisKey][4][1][5].length; i++) { var listId = ServiceArray[Category][thisKey][6][1][i][7]; var listTitle = ServiceArray[Category][thisKey][8][1][i][0]; var List = ""; for (var x = 0; x < ServiceArray[Category][thisKey][9][1][i][10].length; x++) { var Time = ServiceArray[Category][thisKey][11][1][i][12][x][13]; var Content = ServiceArray[Category][thisKey][14][1][i][15][x][0]; var Hours = ServiceArray[Category][thisKey][16][1][i][17][x][18]; List += '<div class="li"><div class="selection"></div><p data-time="' + Time + '">' + Content + '<span class="orange"> ('+ Hours +'Hrs)</span></p></div>'; }$(".layer4").append('<div id="' + listId + '" class="listContainer"><h2>' + listTitle + '</h2><div class="ListWrapper">' + List + '</div></div>');
}
\$(".layer4").append('</div>');
});


So the ultimate question:

Is this method the best for the specific situation, or could I have done something more efficient to save time an effort while achieving the same result?

-

Okay, I think that I have everything that I need from the comments in the original thread. Long story, short, this type of data really needs to be stored in objects.

While not enforced by JS, arrays are really best used for groups of different values for a single type of data (e.g., and array of days of the week, months of the year, etc.). Objects, on the other hand, are a group of different peices of data that all represent aspects about a single "thing" (e.g., a "person" object could contain name, gender, age, height, weight, etc.)

So, given what I can see of your data, what you need are an array of objects (in both cases). PageSplashLists is an array of Category objects, that each also contain an array of options for that Category. ServiceArray appearance to be an array of arrays of Service objects. I'm still not 100% sure of what the relationship is between PageSplashLists and ServiceArray, but let's start with what we have and I can update based on clarifications after the first attempt.

So, for PageSplashLists I would suggest something like this:

PageSplashLists = [
{categoryGroup: "Framework",
inputType: "checkbox",
categories: [
{description: "I have a non-generated website and need it upgraded.",
hours: 1},
{description: "I have a generated website and need it upgraded.",
hours: 2},
{description: "I need a new website created for this.",
hours: 3}
]
},
{categoryGroup: "Design",
inputType: "checkbox",
categories: [
{description: "I have images or examples of what I want this to look like.",
hours: 6},
{description: "I can tell you basically what I want this to look like.",
hours: 8},
{description: "I want you to be creative and design it. Make it amazing.",
hours: 10}
]
},
{categoryGroup: "Graphic",
inputType: "numeric",
categories: [
{description: "I need some custom graphics made.",
hours: 6},
{description: "I need graphic mouseover buttons.",
hours: 3},
{description: "I need [count] stock photos purchased.",
hours: 1}
]
},
. . . .


This way, you would reference each category group by it's array index, but, once "inside" you would reference the properties by their name . . . the same would apply to the categories arrays in each object. So, some examples of the references in the first category group would include:

PageSplashLists[0].categoryGroup (equals "Framework")
PageSplashLists[0].inputType (equals "checkbox")
PageSplashLists[0].categories[0].description (equals "I have a non-generated website and need it upgraded.")
PageSplashLists[0].categories[0].hours (equals 1)


ServiceArray would do something similar to fit its structure:

ServiceArray = [
[{serviceName: "Splash Page",
serviceKey: SplashPage,   // I'm a little unclear as to how you are using these
sampleURL: "http://www.hollowaydesignfirm.com"},
{serviceName: "Gaming Website",
serviceKey: GamingWebsite,
sampleURL: "http://www.faeria.net"},
{serviceName: "Basic Website",
serviceKey: BasicWebsite,
sampleURL: "http://www.innovationsquareboston.com"},
. . . .
],
[
{serviceName: "Basic Application",
serviceKey: BasicApplication,
{serviceName: "Market Application",
serviceKey: MarketApplication,
],
[
{serviceName: "Simple Web Tool",
serviceKey: BasicApplication,
{serviceName: "Industrial Application",
serviceKey: IndustrialApplication,
],
. . . .


You'll notice that I removed the [0]is the id to be assigned to the element. and the [3]is a key value to be appended to each item so I can call on a correlating value in the first array set . . . the first one can be derived from the serviceName property, by using .replace() to get rid of any spaces in the value. For the second one, since the values are sequential and zero-based, can be derived from the index of the array (they are a direct match). Some examples of the references in the first service group would include:

ServiceArray[0][0].serviceName (equals "Splash Page")
ServiceArray[0][1].serviceKey (equals SplashPage)
ServiceArray[0][2].sampleURL (equals "http://www.hollowaydesignfirm.com")


I still feel like I'm missing more of a relationship between the two groups that might impact how they are each structured, but I don't see any information that would let me make those connections with any sense of surety.

Let me know if you have any questions.

-
This is a good answer too. So, what the outcome here appears to be is that the arrays work, but using objects is a more efficient route for working in team based environments and updating data later on. –  Jonathan Todd Jan 31 '14 at 22:08
That and it's a better "data representation" of what you are storing, as referenced in my description of the best practices for using arrays and objects, at the beginning. –  talemyn Jan 31 '14 at 22:14
objects are just array with s –  john Smith Jan 31 '14 at 23:04

While there's nothing completely wrong with what you did, if I were the programmer coming in behind you - I would certainly curse your name. Writing "good" code (to me of course) requires more than meeting the objectives. Readability and maintainability are just as important.

My concern with your design didn't set in until I saw the sample code to build the menu. Seeing all those brackets and indexes just about melted my brain. I think if you would use object literals rather than straight arrays then my problems go away as it should then be much more readable and straight forward.

-
This is a good answer. –  Jonathan Todd Jan 31 '14 at 22:03

I would go with @mklinker. Multi-dimentional arrays are not very readable. I admit they get the job done, but its messy. And the JavaScript, that's just too crazy. A developer will have to go through the array and map the indexes to figure out what they are looking for. Definitely not fun, hard to modify, etc.

I would rather create objects. With objects, you can serialize object to jSON and make your javascript more cleaner and readable. Your server-side code would also be clean. In addition, you wouldn't have a hard time extending the object should you choose to extend/modify your dropdown. You can then support different types of dropdown menus, for different purposes.

Creating a good design might take longer, but it is totally worth it in the long run. Other developers appreciate it too.

-