2
var profileDataCalls = [];

profileDataCalls['Profile'] = GetUserAttributesWithDataByGroup;
profileDataCalls['Address'] = GetUserAddresses;
profileDataCalls['Phone'] = GetUserPhoneNumbers;
profileDataCalls['Certs'] = GetUserCertifications;
profileDataCalls['Licenses'] = GetUserLicenses;
profileDataCalls['Notes'] = GetUserNotes;

My problem is the above JavaScript array is only a length of 0. I need an array that can be iterated over and holds the key(string) and value?

Phrogz
  • 296,393
  • 112
  • 651
  • 745
Mark
  • 2,543
  • 6
  • 33
  • 44
  • Arrays are indexed by number. This is an object with associated attributes, not an array. There is no way to create an associated array like this in javascript. – toby Jan 31 '13 at 20:06
  • 1
    you might want to take a look at the following article: http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/ – Russ Cam Jan 31 '13 at 20:07
  • 1
    This has been asked many times before. See http://stackoverflow.com/a/6709470/1331430 – Fabrício Matté Jan 31 '13 at 20:07
  • possible duplicate of [Loop through array in JavaScript](http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript) – Phrogz Jan 31 '13 at 20:21

4 Answers4

6

You want:

var profileDataCalls = {
    'Profile' : GetUserAttributesWithDataByGroup,
    'Address' : GetUserAddresses,
    'Phone' : GetUserPhoneNumbers,
    'Certs' : GetUserCertifications,
    'Licenses' :GetUserLicenses,
    'Notes' : GetUserNotes
};

Then you can access the values with, for example, profileDataCalls.profile or profileDataCalls[profile] (to retrieve whatever value is represented by the variable GetUserAttributesWithDataByGroup)

To iterate through the object, use:

for (var property in profileDataCalls) {
    if (profileDataCalls.hasOwnProperty(property)) {
        console.log(property + ': ' + profileDataCalls[property));
    }
}
David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • Why, thank you. Though I am assuming predefined variables, of course. Which, given the question, may be unwise. But here's hoping... :) – David Thomas Jan 31 '13 at 20:07
  • 1
    Wouldn't you need to use quotes? i.e. 'Profile', etc. –  Jan 31 '13 at 20:08
  • This still is not an array, and the `length` property will be undefined. – Jeffrey Sweeney Jan 31 '13 at 20:09
  • @Jimmy no, not unless the key is a reserved word or contains special characters. – David Thomas Jan 31 '13 at 20:09
  • @Jeffrey: no, it's *not* an array, but since he can't *use* an array with named keys but seems to want them, he's kinda stuck with an object. – David Thomas Jan 31 '13 at 20:10
  • @David Thomas - exactly, the OP uses string in the assumed associative references –  Jan 31 '13 at 20:11
  • @DavidThomas then could you explain that in your answer to answer the OP's question? – Jeffrey Sweeney Jan 31 '13 at 20:11
  • @DavidThomas that's true but Jimmy has a point and in general it's 'best practice' (in my opinion) to use quotes around object properties (or if you want 'array keys') just in case you accidentally use a preserved word. Or maybe 'Profile' becomes a reserved word in a later javascript version, you don't know.. – Robin van Baalen Jan 31 '13 at 20:12
  • 2
    +1 Now that you've finally answered the *actual* question with your `for...in` loop at the bottom. – mellamokb Jan 31 '13 at 20:12
  • @Jeffrey - referencing the objects would be done by using the keys or a "for in" loop instead of numbers –  Jan 31 '13 at 20:12
  • 1
    @RobinvanBaalen JS versions that introduce new keywords require using a `version` in the script type to don't "break the web". There's no point to quoting it, say, you can't quote `var` names and it'd break the same if you were to use a var name that becomes a keyword. – Fabrício Matté Jan 31 '13 at 20:13
  • @FabrícioMatté didn't know that. Thanks for enlightening me. – Robin van Baalen Jan 31 '13 at 20:16
  • @RobinvanBaalen Well, of course, there's a point that is avoiding existing keywords. For example, when using jQuery you may sometimes pass an object with a `class` property that is a reserved keyword (modern browsers may accept an unquoted `class` property but old IE will choke on it and it is still a [reserved word](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words)). So yeah, you can use quoting to avoid such less evident problems. `=]` – Fabrício Matté Jan 31 '13 at 20:19
  • 1
    @DavidThomas : you're welcome. That edit shouldn't have been approved in the first place :). – Styxxy Jan 31 '13 at 21:37
2

Javascript doesnt have associative arrays per say , what you are doing is adding properties to the Array instance. IE doint something like

profileDataCalls.Notes = GetUserNotes;

so you cant really use length to know how many properties your array would have.

now if your issue is iterating over your object properties , you dont need an array , just use an object :

profileDataCalls = {}

then use a for in loop to iterate over the keys :

for(var i in profileDataCalls ){
 // i is a key as a string
 if(profileDataCalls.hasOwnProperty(i)){
 //do something with profileDataCalls[i] value , or i the key
 }
}

it you have different requirements then explain it.

now the tricky part is profileDataCalls[0]="something" would be valid for an object({}), you would create a property only available through the lookup (obj[0]) syntax since it is not a valid variable name for javascript.

other "crazy stuffs" :

o={}
o[0xFFF]="foo"
// gives something like Object {4095:"foo"} in the console
mpm
  • 20,148
  • 7
  • 50
  • 55
  • Yes, JavaScript does have associative arrays _per se_; they are objects. – Phrogz Jan 31 '13 at 20:23
  • @Phrogz i disagree , because adding keys (which are strings ) should increment the length of the array in a associative array , which is not the case in Javascript. – mpm Jan 31 '13 at 20:26
  • You are entitled to your opinion about what an "associative array" is. Mine matches this: http://en.wikipedia.org/wiki/Associative_array (Note that there is no mention of `length` on that page. The name "associative array" is a poor name because it has nothing to do with ordered storage.) – Phrogz Jan 31 '13 at 20:29
  • @Phrogz Well i disagree with that definition which is too broad in my opinion, and Wikipedia is not always truthfull, if something doesnt have a length it is not an array.If adding an "association" doesnt increment the length of that array it is not an array. If something is not iterable it is not an array , in some languages , maps are not iterable. – mpm Jan 31 '13 at 20:31
2

Actually it also works like this:

var profileDataCalls = [{
    Profile: GetUserAttributesWithDataByGroup(),
    Address: GetUserAddresses(),
    Phone: GetUserPhoneNumbers(),
    Certs: GetUserCertifications(),
    Licenses: GetUserLicenses(),
    Notes: GetUserNotes()
}];

Then you can access the values with, for example, profileDataCalls[0].profile or profileDataCalls[0]["profile"].

To iterate through the object, you can use:

for (key in profileDataCalls[0]) {
   console.log(profileDataCalls[0][key]);
}

Since this is an associative array, I never understood why people are saying its not possible in Javascript...in JS, everything is possible.

Even more, you could expand this array easily like this:

var profileDataCalls = [{
    Profile: GetUserAttributesWithDataByGroup(),
    Address: GetUserAddresses(),
    Phone: GetUserPhoneNumbers(),
    Certs: GetUserCertifications(),
    Licenses:GetUserLicenses(),
    Notes: GetUserNotes()
}{
    Profile: GetUserAttributesWithDataByGroup(),
    Address: GetUserAddresses(),
    Phone: GetUserPhoneNumbers(),
    Certs: GetUserCertifications(),
    Licenses: GetUserLicenses(),
    Notes: GetUserNotes()
}];

And access the array entries with profileDataCalls[0]["profile"] or profileDataCalls[1]["profile"] respectively.

Marcus
  • 1,222
  • 2
  • 13
  • 22
1

What you want is an object:

Try

    var profileDataCalls = new Object();

then reference your data as you do already.