I get the feeling after some googling that a lot of lodash's functions can be achieved with native typescript but i cannot find a straightforward answer for the _.get function...
In lodash the following, using the _.get function alerts 1
let obj = {a:{b:1}};
let a = _.get(obj, 'a.b');
alert(a);
Is there a way of achieving the same result with only typescript?
I get the feeling after some googling that a lot of lodash's functions can be achieved with native typescript but i cannot find a straightforward answer for the _.get function...
In lodash the following, using the _.get function alerts 1
let obj = {a:{b:1}};
let a = _.get(obj, 'a.b');
alert(a);
Is there a way of achieving the same result with only typescript?
Share Improve this question asked Oct 20, 2016 at 8:49 user1037355user1037355 3- I haven't found any real-life scenarios for this, but could anyone tell me why the .get() function is even useful instead of prop notation? Is it only for the ability to return a default value if the path is undefined? – Felipe Commented May 23, 2017 at 14:31
- @felipe: IMHO that's when you need to access a dynamic "path" into properties of an object with a depth unknown in advance. – FGM Commented Sep 24, 2018 at 14:03
- Does this answer your question? Accessing nested JavaScript objects and arrays by string path – Rafael Tavares Commented Sep 22, 2021 at 14:24
3 Answers
Reset to default 13In plain Javascript you could split the path and reduce the path by walking the given object.
function getValue(object, path) {
return path.
replace(/\[/g, '.').
replace(/\]/g, '').
split('.').
reduce((o, k) => (o || {})[k], object);
}
var obj = { a: { b: 1 } },
a = getValue(obj, 'a.b');
console.log(a);
/**
* Get value of a property from a nested object.
* Example:
* var x = { a: {b: "c"} };
* var valueOf_b = getDeepValue(x, ["a", "b"]);
*
* @param {object} Object The Object to get value from
* @param {KeyArray} Array[String] An array of nested properties. ex. ["property", "childProperty"]
*/
const getDeepValue = (object, keyArray) => {
const extractValue = (obj, kArray) => {
const objProperty = obj[kArray[0]];
if (kArray.length >= 1) {
const newKeyArray = kArray.splice(1, kArray.length);
if (newKeyArray.length === 0) return objProperty;
return extractValue(objProperty, newKeyArray);
}
return objProperty;
};
try {
const value = extractValue(object, keyArray.slice());
if (value === undefined || typeof value === 'object') {
console.warn("Unable to retrieve value from object for key ", keyArray);
return '';
} else {
return value;
}
} catch (e) {
console.warn("Exception: Unable to retrieve value from object for key ", keyArray);
return '';
}
};
Maybe slightly cleaner alternative using an ES6 default parameter:
const get = (o, path) => path.split('.').reduce((o = {}, key) => o[key], o);
console.log(get({ a: { b: 43 } }, 'a.b')); // 43
The above digs all the way to the bottom even when it encounters undefined. An alternative is recursion, you'll have to split before invoking it:
function get(object, [head, ...tail]) {
object = object[head];
return tail.length && object ? get(object, tail) : object;
}
console.log(get({ a: { b: 43 } }, 'a.b'.split('.'))); // 43