I need to get the last key of an object which has a value. So if this would be the object...
const obj = { first: \'value\', second: \'something\', third: undefi
If you need to get the "last property with a value," you're using the wrong data structure. An object is just not a good fit. You want to use an array or a Map
. I'd probably use a Map
as shown by Andrew Li, since it defines a useful order and also key-based lookup.
If you insist on using an object: Object properties do have an order as of ES2015 (aka "ES6"). That order is only enforced by certain operations; it isn't enforced by for-in
or Object.keys
. It is enforced by most other operations, including Object.getOwnPropertyNames
(ES2015), the upcoming Object.values
in the ES2017 specification, and (interestingly) JSON.stringify
.
However, the order is unlikely to be very useful to you. Assuming we're only talking about "own" properties whose names are not Symbols, the order is: Any property that's an "integer index" as defined by the specification1, in numeric order, followed by any other properties, in the order they were added to the object.
You see why an object is the wrong structure for this: Integer indexes get priority over other properties, so given:
const obj = { first: 'value', second: 'something', third: undefined, 42: 'value' };
...using the object's order, we'll say that the last value is 'something'
when it should be 'value'
. Using a Map
, you'd get the right answer.
So, I don't recommend using an object for this, but if you insist on doing so, here's how you can do it on a fully-compliant ES2015+ JavaScript engine:
function test(testNumber, obj) {
const last = Object.getOwnPropertyNames(obj).reduce((currentValue, key) => {
const value = obj[key];
return typeof value === "undefined" ? currentValue : value;
}, undefined);
console.log(`Test #${testNumber}: '${last}'`);
}
// This says 'something' (value of `second`):
test(1, { first: 'value', second: 'something', third: undefined, fourth: undefined });
// This says 'else' (value of `third`):
test(2, { first: 'value', second: 'something', third: 'else', fourth: undefined });
// This says 'something' (value of `other`):
test(3, { any: 'value', other: 'something', thing: undefined, bla: undefined });
// BUT! This says 'something' (value of `second`), not 'value' (value of `42`)!
test(4, { first: 'value', second: 'something', third: undefined, 42: 'value' });
.as-console-wrapper {
max-height: 100% !important;
}
Note that last result.