Javascript: Get deep value from object by passing path to it as string
Consider this:
var obj = {
foo: { bar: 'baz' }
};
function deepFind(obj, path) {
var paths = path.split('.')
, current = obj
, i;
for (i = 0; i < paths.length; ++i) {
if (current[paths[i]] == undefined) {
return undefined;
} else {
current = current[paths[i]];
}
}
return current;
}
console.log(deepFind(obj, 'foo.bar'))
How to Get the Value of nested JavaScript object property by string key
You can use helper function to achieve this, e.g.:
var data = {
cont: {
model: {
Inspection: {
InspectionName: "Hello world"
}
}
}
};
function getNestedValue(obj, key) {
return key.split(".").reduce(function(result, key) {
return result[key]
}, obj);
}
console.log(getNestedValue(data, "cont.model.Inspection.InspectionName"));
Js or ES6 Get object field by path string when field has 2 or more nested levels as in myObj.one.two.three.field
option #1 (not recommended) - use the eval
function:
var projects = {
a : {
b : {
c : 1
}
}
}
function get(myPath) {
debugger;
return eval("projects." + myPath)
}
console.log(get('a.b.c'))
Accessing nested JavaScript objects and arrays by string path
I just made this based on some similar code I already had, it appears to work:
Object.byString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}
Usage::
Object.byString(someObj, 'part3[0].name');
See a working demo at http://jsfiddle.net/alnitak/hEsys/
EDIT some have noticed that this code will throw an error if passed a string where the left-most indexes don't correspond to a correctly nested entry within the object. This is a valid concern, but IMHO best addressed with a try / catch
block when calling, rather than having this function silently return undefined
for an invalid index.
Set value in object by path and flatten again with objects and arrays
I have totally reworked the deepSet function now. It now supports multiple arrays and gaps in the arrays etc. I think this covers now every usecase. In the end it was way easier to figure the logic out when I started over without the reduce function
export const deepSet = (obj: any, path: string, val: any) => {
path = path.replaceAll("[", ".[");
const keys = path.split(".");
for (let i = 0; i < keys.length; i++) {
let currentKey = keys[i] as any;
let nextKey = keys[i + 1] as any;
if (currentKey.includes("[")) {
currentKey = parseInt(currentKey.substring(1, currentKey.length - 1));
}
if (nextKey && nextKey.includes("[")) {
nextKey = parseInt(nextKey.substring(1, nextKey.length - 1));
}
if (typeof nextKey !== "undefined") {
obj[currentKey] = obj[currentKey] ? obj[currentKey] : (isNaN(nextKey) ? {} : []);
} else {
obj[currentKey] = val;
}
obj = obj[currentKey];
}
};
How to store a object path
You could use an array for the keys and a function wich reduces the object by using the keys for the property access.
const getValue = (object, path) => path.reduce((r, k) => (r || {})[k], object);
var object = { india: { chennai: { sholing: "hi" } } }, path = ['india', 'chennai', 'sholing'];
console.log(object.india.chennai );console.log(getValue(object, path));
Getting a value from a JSON object by its path
You could reduce the object with the splitted path values.
var object = { result: { data: { point1: "x", value: 2 }, foo: { bar: 7 } } }, path = 'result.data.value', getValue = (o, p) => p.split('.').reduce((r, k) => r[k], o);
console.log(getValue(object, path));
Find a full object path to a given value with JavaScript
Use a recursive function to look for the item you want. Once the function find it, it will return an array. Each step back of the recursion will unshift
the object key of this step:
function find(obj, item) {
for(var key in obj) { // for each key in obj (obj is either an object or an array)
if(obj[key] && typeof obj[key] === "object") { // if the current property (value of obj[key]) is also an object/array
var result = find(obj[key], item); // try finding item in that object
if(result) { // if we find it
result.unshift(key); // we shift the current key to the path array (result will be an array of keys)
return result; // and we return it to our caller
}
} else if(obj[key] === item) { // otherwise (if obj[key] is not an object or array) we check if it is the item we're looking for
return [key]; // if it is then we return the path array (this is where the path array get constructed)
}
}
}
The output of this function will be an array of keys leading to item
. You can easily transform it to the format in the question:
function findFormatted(obj, item) {
var path = find(obj, item); // first let's get the path array to item (if it exists)
if(path == null) { // if it doesn't exist
return ""; // return something to signal its inexistance
}
return 'myObj["' + path.join('"]["') + '"]'; // otherwise format the path array into a string and return it
}
Example:
function find(obj, item) { for(var key in obj) { if(obj[key] && typeof obj[key] === "object") { var result = find(obj[key], item); if(result) { result.unshift(key); return result; } } else if(obj[key] === item) { return [key]; } }}
function findFormatted(obj, item) { var path = find(obj, item); if(path == null) { return ""; } return 'myObj["' + path.join('"]["') + '"]';}
var myObj = [{"name":"group1","children":[{"name":"group2","children":[{"name":"item0"}]}]},{"name":"item1"},{"name":"needleGroup","children":[{"name":"needleNestedGroup","children":[{"name":"item3"},{"name":"needleNestedDeeperGroup","children":[{"name":"needle"}]}]}]}];
console.log("find(myObj, \"needle\"): " + JSON.stringify(find(myObj, "needle")));console.log("findFormatted(myObj, \"needle\"): " + findFormatted(myObj, "needle"));
Related Topics
Set a Callback Function to a New Window in JavaScript
Cannot Access CSSrules from Local CSS File in Chrome 64
Jquery: How to Listen for Dom Changes
How to Limit Options Selected in a HTML Select Box
How to Disable Copy Paste (Browser)
Js: Get Array of All Selected Nodes in Contenteditable Div
How to Listen/Detect Changes to an Input Value - When the Input Value Is Changed via JavaScript
How to Reach the Element Itself Inside Jquery's 'Val'
Html5 Drag & Drop Change Icon/Cursor While Dragging
How to Set HTML Content into an Iframe
Animated Gif Only Loops Once in Chrome and Firefox
How to Play a Notification Sound on Websites
Jquery - Multiple $(Document).Ready ...
$(Document).Click() Not Working Correctly on Iphone. Jquery