-2

It seems to me that one of the big downsides of javascript is that there are no associative arrays. Objects don't provide order, arrays don't provide keys.

There is also the possibility of arrays containing objects:

[{key1:value1}, {key2:value2}]

But as far as I know, there is no easy way to access elements by keys in this approach (without having to iterate through all elements).

That's why I started to think about the following approach, that is making an array associative by adding a element mapper:

Array.prototype.addKeyToLastElement = function(key) {
    if (!this.elementMapper) this.elementMapper = {};
    this.elementMapper[key] = this.length-1;
}
Array.prototype.getElementByKey = function(key) {
    if (this.elementMapper && this.elementMapper[key] !== undefined) {
        return this[this.elementMapper[key]];
    }
    else {
        return undefined;
    }
}

var test = [];
test.push(1);
test.addKeyToLastElement('a');
test.push(3);
test.addKeyToLastElement('b');

// get element by key
console.log(test.getElementByKey("a"));

I know that this is far from perfect, it's just a first try to see if it works. I was just wondering why I couldn't find any similar solutions.

Is this approach deprecated? If yes, what are the best alternatives?

My minimal requirements are:

  1. Access elements by keys (retrieve/ alter value)
  2. Maintain the elements order
  3. Sort elements both by key and value
Idos
  • 15,053
  • 14
  • 60
  • 75
am2124429
  • 425
  • 2
  • 6
  • 8
  • Have a look at ES6 maps: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map. Altering native prototypes is considered bad practice. – nils Mar 03 '16 at 11:49
  • there are libraries that solve these problems, there is no need to reinvent wheels especially when working with prototype – Gntem Mar 03 '16 at 11:52
  • @am2124429 What do you mean by _"arrays don't provide keys"_ ? Do you want to access an element of an array using letters ? e.g., `arr[a]` ? – guest271314 Mar 03 '16 at 12:03
  • Unfortunately best practice centred questions are not a good fit for Stack Overflow as they will mainly spawn opinion-based answers ("I like doing it this way...", "people generally use this..."). While you may see answers on other questions based on what the author considers "best practice", specifically asking for them is off-topic. For more information, see the [help]. – Kyll Mar 03 '16 at 12:48
  • @GeoPhoenix: That would be a great help. Can you please give an example? – am2124429 Mar 22 '16 at 08:16
  • @Kyll: I see. I should have asked: why is this considered bad practice ... but I wasn't absolutely sure that it is, that's why I kept the "why" out of my question. – am2124429 Mar 22 '16 at 09:03
  • Even the "why" is subjective. What could be on-topic is rather "What are the technical implications of changing `Array.prototype`", although it may be a bit broad and has probably been asked before. If you wish to discuss further about the scope of your post and how to edit it, feel free to drop into [SOCVR](https://chat.stackoverflow.com/rooms/41570/so-close-vote-reviewers). Note that editing will be hard in that case since there already are answers and an edit shouldn't invalidate them. – Kyll Mar 22 '16 at 09:55

2 Answers2

1

Is this approach deprecated? If yes, what are the best alternatives?

It is not deprecated, but it is not a good idea and hence a bad coding practice for following main reasons

  • These extra properties are not included in JSON serialisation.
  • These properties would be thrown away if you do an array operation like arr = arr.slice(1) which leads to un-expected behaviour.

But you can still sort the object like this (in your question)

[{key1:value1}, {key2:value2}]

by doing

var arr = [{key1:value1}, {key2:value2}];
arr.sort(function(a,b){

    return a[Object.keys(a)[0]] - b[Object.keys(b)[0]];

})
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
1

arrays don't provide keys

But as far as I know, there is no easy way to access elements by keys in this approach (without having to iterate through all elements)

If interpret Question correctly, you could assign an alphabetic or other "key" as an index identifier and use a numeric identifier to access the same element within the array

var alphabet = "abcdefghijklmnopqrstuvwxyz";

var arr = [];

for (var i = 0; i < alphabet.length; i++) {
  arr[alphabet[i]] = arr[i] = alphabet[i]
};

console.log(arr["a"], arr[0], arr["z"], arr[25])
guest271314
  • 1
  • 15
  • 104
  • 177
  • I didn't know that it was so easy: `arr["myKeyToArr0"] = arr[0];`. That's exactly what I have been looking for. Can anyone tell me how this is called or where I can find further reading on this? – am2124429 Mar 22 '16 at 08:33
  • See http://stackoverflow.com/questions/21293063/how-to-programmatically-enumerate-an-enum-type-in-typescript-0-9-5 – guest271314 Mar 22 '16 at 09:11
  • The thread seems to be neither about javascript nor about arrays. Or am I missing something? – am2124429 Mar 24 '16 at 11:46
  • @am2124429 See http://stackoverflow.com/questions/35517865/is-it-possible-to-store-both-a-number-and-name-for-a-value-in-an-array/ , https://jsfiddle.net/zv4zga3a/ – guest271314 Mar 24 '16 at 16:21