0

I have a list of users, with minions, something like this:

User52:
       minion10
       minion12
User32:
      minion13
      minion11

I've been keeping in an array where the "location" is the id, like this:

Users:
       [52]User
               minions:
                       [10]minion
                       [12]minion
       [32]User
               minions:
                       [13]minion
                       [11]minion

so I can access them easily like this: user[UserID].minions[MinionID] (ex: user[32].minions[11]).

But when I print it or send it by json I get something like this:

{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,minion,,,,,,,,,,,,,,minion}

But should I keep using like this or should I change to something like this:

User = function(){
   this.minions = ...;
   this.getMinion = function(value){
     for(var m in this.minions){
      if(this.minions[m].id == value){
         return this.minions[m];
         break;
      }
     }
   } 
}

and get it like this:

user.getMinion(MinionID);

Question: I get better performance using a "short" array but using loops every time I need a minion, or using "long" arrays, but no need for loop and getting values directly from the id "name"?

2
  • I'm sorry, what?
    – Zirak
    Commented Jun 19, 2012 at 15:09
  • @Zirak question updated, sorry
    – Joaolvcm
    Commented Jun 19, 2012 at 22:24

2 Answers 2

2

Mr. Melo raise a good question for JavaScript Object Access Pattern. I leave the prior 'introductory' answer for others to interpret your code.

My answer is to override a print method, and another way, to convert the data into a human-readible data-translation.

when print it or send it by json you get non sensible output:

{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,minion,,,,,,,,,,,,,,minion}

Here is where I can give a suggestion. What you are seeing above is the Object-Literal converted to string. Perhaps nested in a JSON.stringify() method or another perhaps toString() use. You can improve this with two potential solutions depending on your context.

A ToString Method Override. - One solution is to dig into the function (step-debug) 'down-into' the method that is converting your object to String, and copy, rename, and change it to yourOwnStringifyMethod(). This is an essentially a toString() method override. Instead of printing

","+","+","+data+",",

override it to print something else. Call it minion.minionToString() or something.

Indices could easily be inserted in the iterator to produce:

{0,1,2,data,...}

Or Print the id of a minion by printing the data-members like +minion.name+. Search for toString override, this would be perhaps ideal, if you are transferring the JSON asynchronously, or real-time web-sockets, and just want to translate the data.

B. Templates. If the data is to be viewed on screen, instead of transferred, data-bind it from json to a template. Data-binding is great. The syntax is something like var arg = " <html>...<div><%data-field*></div></html>" Then you send that into a templ(arg) function, for example, and it spits out a var x = templ(htmltemplate, data-stream). Var x is now your template-data-loaded-html to be inserted into the dom.

There are a number of ways to do this.

C. This is an interesting incarnation of code where you hint:

i've been keeping in an array where the "location" is the id

That reminds me somehow of CouchDB. CouchDB and Mongo are JavaScript Databases, that use JSON objects persisted over time by a long unique ID. Maybe this will help you evolve an accessor and display best-practice.

D. The lookup function loop looks potentially costly for very-large data-sets. There are certain indexing and search algorithms that can cut down on processing iterations if you are running a high number of minions, and wish to optimize lookup. Paul Irish wrote a book, or paper, on 10 things that I learned by reading jQuery source code. I imagine there is some advanced fruit in there about efficient dom node traversal, which could, in the least, be enlightening to your armament of minions.

Hope that helps. All the best! Nash

2
  • I actually need to take care of some data before sending, so i'm actually already avoiding this before printing/sending.. so , you are telling me that the big empty array problem only happens on converting data to string/json, and this minions[999999] = "A", if i don't convert it , is as big and resource heavy as this: minions[0] = "A"?
    – Joaolvcm
    Commented Jun 20, 2012 at 10:54
  • No, looping over 999999 elements could be potentially optimized given your context.
    – Jack Stone
    Commented Jun 20, 2012 at 14:13
1

Good question. This is a common confusion early on.

What you are seeing is a different syntax of two things that behave the same because they are both objects. I will get to exactly why this is but will first clarify what is what:

In JavaScript,

This is an Array:

var arrayExample[];

This is an Object Literal:

var jsObject = {};

To answer your question, you should use Array definition and access syntax, when your intent is to use an Array.

user[15] = USER;
for (var i in user){
  if(user[i].id == ID){
    user[i];
}

That said, there are better Array operations frameworks out there. One is underscore.js. But only consider it if you are conducting a large number of array operations that could be optimized. Another optimization is the jQuery foreach(), which is worth looking into.

Because an array is an object, and because objects have a naming lookup [] syntax, they have similar behavior. Both are very powerful constructs, but you should use them as they are intended so that subsequent developers can easily interpret your intentions.

The behavior overlap between object and array, is actually a very powerful flexibility of the language that is commonly misunderstood.

Here is a good link, but I'll try to make it simple.

An Object can access its' members through this name look up syntax:

//Looks like an array, but is an object accessing a member value, not an index value. var memberValue = jsObject['member-name']

Essentially arrays are then doing the same thing, just with a number instead of a string.

Again, use an Array - when you need an Array, and Object - when you need an Object.

2
  • question updated, sorry @ClintNash
    – Joaolvcm
    Commented Jun 19, 2012 at 22:23
  • 1
    Why are you proposing libraries when forEach does the job? He's usingnode.js, so there is no compatibility matters involved. Commented Jun 20, 2012 at 6:18

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.