0

I only want to define an empty object dct[dpid] if does not already contain data. This seems a bit clunky, is there a better way to write it?

dct = {}; //global scope

Later in a function with dpid defined as a string

dct[dpid] = typeof(dct[dpid])=="undefined" ? {} : dct[dpid];
Andy Gee
  • 3,149
  • 2
  • 29
  • 44
  • 1
    You really should use a *hasOwnProperty* test since `dct[dpid]` may exist but have the value *undefined*. – RobG Jun 13 '14 at 05:53

3 Answers3

3

The logical OR operator is commonly used as shorthand:

dct[dpid] = dct[dpid] || {};

Though this only works correctly if the value of dct[dpid] can only be a truthy value. It would incorrectly overwrite dct[dpid] = 0 for example. But if your property can hold different data types, then that's probably an indicator for poor design.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • It's another object if it is set. Does that qualify as truthy? – Andy Gee Jun 13 '14 at 05:55
  • 1
    Yes, all objects are truthy. – Felix Kling Jun 13 '14 at 05:55
  • @AndyGee—yes. All objects evaluate to true (well, except null, but it's not *really* an object). Also beware host objects, they may seek to differ. – RobG Jun 13 '14 at 05:56
  • Works like a charm and looks great too – Andy Gee Jun 13 '14 at 05:59
  • "But if your property can hold different data types, then that's probably an indicator for poor design." - I think the disclaimer about falsy values is still valid, as a general precaution: you could have `x[y] = x[y] || 1` and have it fail at `0`, with the perfectly good design of having all values numeric. – Amadan Jun 13 '14 at 05:59
  • @Amadan: Yes of course. The statement is to be understood in this specific context, where the default value is supposed to be an object. If you'd work with numbers instead, you shouldn't use `||`. – Felix Kling Jun 13 '14 at 06:01
  • @Amadan Point taken but for me at least it's going to be an object full of arrays of strings or undefined. – Andy Gee Jun 13 '14 at 06:04
  • "If you'd work with numbers instead, you shouldn't use `||`" Meh... again, too much generalisation :) When you're counting frequencies, `x[y] = x[y] || 0` is perfectly reasonable. :D I'm mainly worried about people stumbling onto the question later, then taking away the wrong message (rather than, "know what your data contract is"). You already have an upvote from me, so I'm totally not disagreeing with you - this already works perfectly for OP. :) – Amadan Jun 13 '14 at 06:05
0

you could do:

dct = {};
dct[dpid] = (!!dct[dpid]) ? {} : dct[dpid];

or

dct[dpid] = dct[dpid] || {}; //defaults to empty object
Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
  • You might as well just `dct[dpid] = dct[dpid] || {}` – elclanrs Jun 13 '14 at 05:52
  • 1
    Needs disclaimer: works great with a contract that you won't have falsy values. Breaks down if you allow `null` or `""` or `0` or `false` or `undefined`. EDIT: `NaN` too. Dangit. – Amadan Jun 13 '14 at 05:52
  • What if `dct[dpid]` has some falsy value other than *undefined*? Like `null`, `0`, `NaN`, … – RobG Jun 13 '14 at 05:54
  • `!!x` and `x` are equivalent when in a condition; you don't need that. – Amadan Jun 13 '14 at 05:57
0

No need for ternary operator:

if (typeof(dct[dpid])=="undefined")
    dct[dpid] = {};

But why not just initialise it at the start?

dct = { dpid: {} };
  • a) using `dct.hasOwnProperty(dpid)` is safer than `typeof(dct[dpid])=="undefined"`; b) say you want to transform a list of edges into a dictionary of vertices to adjacent vertices; you don't know at the start how you'd construct it. – Amadan Jun 13 '14 at 06:02