4

I know how to grab array by its index. Also I know how to grab objects by its key, but I don't want to grab it by key.

Here you go for my objects

var x = {"email":["This Position"]}

And I know I can grab This Position like writing x.email[0].

But the problem is, I can't always grab the This Position with x.email[0].

Because the server sometimes sends me like this:

var x = {"phone":["This Position"]}

Even some time like this: var x = {"name":["This Position"]}

So you know to grab This Position not possible, because, for those variable, I have to write like x.phone[0] or x.name[0].

And it is very tough to write for hundred of variables.

 var x = {"email":["This Position"]}

So I want to grab This Position not with like this x.email[0].

Can give you me a solution that whatever key name, I just want to grab first first value first key? Is it possible?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
dudd
  • 312
  • 2
  • 11

3 Answers3

3

You can use Object.values

var x = {"email":["This Position"]}
var value = Object.values(x)[0][0]
Anurag Srivastava
  • 12,230
  • 3
  • 21
  • 36
3

Use Object.values like so:

var x = {"email":["This Position"]};
const [[res]] = Object.values(x);
console.log(res);
Jack Bashford
  • 38,499
  • 10
  • 36
  • 67
3

This is possible in implementations where JavaScript objects are ordered by insertion sequence. This answer along with the other answers in the thread offers a good overview of when you can rely on this and under what restrictions. The rest of this answer assumes ordering is guaranteed by the ES implementation.

The most direct solution is to use Object.values(obj)[0], Object.keys(obj)[0] or Object.entries(obj)[0]. However, these methods visit every entry in the object which results in O(n) time complexity, so these approaches are only valuable for simple use cases that aren't performance-critical.

const obj = {
  foobar: ["This position"],
  foobaz: ["That position"]
};

// succinct but linear:

console.log(Object.keys(obj)[0]);
console.log(Object.values(obj)[0]);
console.log(Object.entries(obj)[0]);

// since you want the first array element of the first value, use:
console.log(Object.values(obj)[0][0]);

Faster is to iterate over the keys with in and return the first. This requires a bit more code but offers a massive complexity improvement for large objects.

// use a loop and return after the first element, O(1):

const getFirstVal = obj => {
  for (const k in obj) return obj[k];
};

const getFirstKey = obj => {
  for (const k in obj) return k;
};

const getFirstEntry = obj => {
  for (const k in obj) return [k, obj[k]];
};

const obj = {
  foobar: ["This position"],
  foobaz: ["That position"]
};

console.log(getFirstVal(obj));
console.log(getFirstKey(obj));
console.log(getFirstEntry(obj));

A general solution to the "first n entries" problem is to create a generator version of Object.entries. You can use the generator to step through the object's entries, only going as far as you need and as you need it.

The downside is that there's a bit of generator management for the caller, but this can be abstracted with a function. Use this for cases when you anticipate that you might need more than just the first entry in performance-critical code.

// use a generator function for maximum flexibility

function *iterEntries(obj) {
  for (const k in obj) yield [k, obj[k]];
}

const firstEntries = (obj, n=1) => {
  const gen = iterEntries(obj);
  return Array(n).fill().map(_ => gen.next().value);
};

/* warning: linear search */
const entryAtIndex = (obj, i) => {
  const gen = iterEntries(obj);
  
  while (i--) gen.next();
  
  return gen.next().value;
};

const obj = Object.fromEntries(
  Array(26).fill().map((_, i) => [String.fromCharCode(i + 65), i])
);

console.log(iterEntries(obj).next().value);
console.log(firstEntries(obj, 4));
console.log(entryAtIndex(obj, 4));

You can make versions specific to values or keys as desired. As shown, this technique is also effective for "indexing" into the n-th key of an ordered object. If you find you're doing this frequently, though, consider using an array instead of (or alongside of) an object which is the correct data structure for random index access.

ggorlen
  • 26,337
  • 5
  • 34
  • 50
  • The performance of `Object.keys` should not be a problem. It's clearer, cleaner code. Premature optimization is the root of all evil. – Tom May 19 '19 at 08:42