28

I don't seem to be able to define something like:

var a = {-1: 'Apple', -2: 'Orange'}

my Safari complains about a syntax error near '-'. Parens don't help either, i.e. {(-1): ... - in that case Safari doesn't like the opening paren.

If I want the keys to be just ints, not strings, what is the proper way of constructing an assoc array, if any?

mojuba
  • 11,842
  • 9
  • 51
  • 72

5 Answers5

35

See section 11.1.5 of ECMAScript Language Specification: there you will see that PropertyName may indeed be a NumericLiteral, but section 7.8.3 of the specification indicates that NumericLiteral may not start with the minus sign. What looks like negative "literals" in your example are actually expressions composed of the unary operator - and NumericLiterals.

However, PropertyName may not be an expression: it can only be an identifier name, a numeric literal or a string literal which suggests that you can write

{'-1': 'Apple', '-2': 'Orange'}

Thanks to GetFree for finding the correct explanation!

Community
  • 1
  • 1
Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
  • 2
    That's not the reason. The part you quote explains that numeric literals are internally converted to strings anyways so there is no difference between both when used as keys. The actual reason why you can't use negative numbers is because a negative number is an expression (a minus sign followed by a numeric literal) and you cannot use expresions as keys in an object literal. – GetFree Sep 08 '13 at 15:08
  • You're right. Section 7.8.3 implies that numerical literals may not start with a minus and section 11.1.5 implies expressions may not be property names. This is indeed the right explanation. Thanks! – Adam Zalcman Sep 08 '13 at 16:21
22

Just wrap them in quotes. You can still access with numbers:

var a = {"-1": 'Apple', "-2": 'Orange'}
a[-1]; // Apple;
Dennis
  • 32,200
  • 11
  • 64
  • 79
  • That's obvious, I said in the question that I need them to be ints, not strings. The correct answer is that internally keys are always strings so there is no reason not to quote them. – mojuba Nov 18 '11 at 12:21
  • What exactly does "I need them to be ints" mean? You can't supply negative numbers because key needs to be a literal value and `-` is the unary negative operator, making it an expression. – Dennis Nov 18 '11 at 12:29
  • In JavaScript, when you expect something to be a number rather than a string may have consequences, e.g. `i + 1` yields different results depending on the type of `i`. But this question is answered already: in JavaScript keys are always converted to strings. – mojuba Nov 18 '11 at 12:43
  • The `+` operator is overloaded, but `a["1"]` is the same as `a[1]`. I'm not sure what behavior you expected to differ. – Dennis Nov 18 '11 at 13:47
  • Consider `for (var i in a) { if (a[i + 1])...`. It's good to know that `i` is always a string no matter how you constructed your array. – mojuba Nov 18 '11 at 14:48
5

Quoting works for me:

var a = {'-1': 'Apple', '-2': 'Orange'};
console.log(a[-1]);
aurora
  • 9,607
  • 7
  • 36
  • 54
4

I hit this case recently and one thing new with ES6 as of 2018 is you can simply do that:

var a = {[-1]: 'Apple', [-2]: 'Orange'}

you can even pass variables there (this should give same result as the one above):

var i = 0;
var a = {[--i]: 'Apple', [--i]: 'Orange'}

as mentioned here https://stackoverflow.com/a/11508490/9063787.

2

There is no way to make keys negative integers. If you want to do a negative key you'll have to make them strings like this:

var a = {"-1": 'Apple', "-2": 'Orange'}

You can then do conversions back and forth with parseInt and toString in your other code if needed.

Ben L
  • 2,491
  • 1
  • 16
  • 7