In this stackoverflow thread, i learnt you can get a object path via a simple string.
Accessing nested JavaScript objects with string key
consider the following:
var person = { name: "somename", personal: { weight: "150", color: "dark" }};
var personWeight = deep_value(person,"personal.weight");
I an trying to construct an array of the object values who are not of type 'object' from my 'person' object.
Hence the array would look like:
[['name', []],['personal.weight', []],['personal.color', []]];
I want them to look in that form because i have further use for it down the road.
That's what I've tried:
var toIterate = { name: "somename", personal: { age: "19", color: "dark" } }
var myArray = [];
$.each(toIterate, recursive);
function recursive(key, value) {
if (key !== null) {
myArray.push([key, []]);
}
else {
$.each(value, recursive);
}
}
console.log(myArray);
In this stackoverflow thread, i learnt you can get a object path via a simple string.
Accessing nested JavaScript objects with string key
consider the following:
var person = { name: "somename", personal: { weight: "150", color: "dark" }};
var personWeight = deep_value(person,"personal.weight");
I an trying to construct an array of the object values who are not of type 'object' from my 'person' object.
Hence the array would look like:
[['name', []],['personal.weight', []],['personal.color', []]];
I want them to look in that form because i have further use for it down the road.
That's what I've tried:
var toIterate = { name: "somename", personal: { age: "19", color: "dark" } }
var myArray = [];
$.each(toIterate, recursive);
function recursive(key, value) {
if (key !== null) {
myArray.push([key, []]);
}
else {
$.each(value, recursive);
}
}
console.log(myArray);
Share
Improve this question
edited May 23, 2017 at 12:08
CommunityBot
11 silver badge
asked Aug 21, 2015 at 13:15
TotalWarTotalWar
3551 gold badge8 silver badges16 bronze badges
5
|
4 Answers
Reset to default 11Just use recursion to walk the object.
var person = {
name: "somename",
personal: {
weight: "150",
color: "dark",
foo: {
bar: 'bar',
baz: 'baz'
},
empty: {
}
}
};
// however you want to do this
var isobject = function(x){
return Object.prototype.toString.call(x) === '[object Object]';
};
var getkeys = function(obj, prefix){
var keys = Object.keys(obj);
prefix = prefix ? prefix + '.' : '';
return keys.reduce(function(result, key){
if(isobject(obj[key])){
result = result.concat(getkeys(obj[key], prefix + key));
}else{
result.push(prefix + key);
}
return result;
}, []);
};
var keys = getkeys(person);
document.body.innerHTML = '<pre>' + JSON.stringify(keys) + '</pre>';
Then use Array.prototype.map
to massage the array of keys into your preferred format.
Note the behaviour with person.personal.empty
.
This does seem like a strange way to store an object's keys. I wonder what your 'further use for it down the road' is.
This is what worked for me. Note that, a raw
map is created first and then mapped
to an join
the items
in the Array
with .
.
var toIterate = {
name: "somename",
personal: {
age: "19",
color: "dark"
}
};
console.log(getObjPath(toIterate).map(item => item.join('.')));
function isObject(x) {
return Object.prototype.toString.call(x) === '[object Object]';
};
function getObjPath(obj, pathArray, busArray) {
pathArray = pathArray ? pathArray : [];
if (isObject(obj)) {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (isObject(obj[key])) {
busArray = busArray ? bussArray : [];
busArray.push(key);
getObjPath(obj[key], pathArray, busArray);
} else {
if (busArray) {
pathArray.push(busArray.concat([key]));
} else {
pathArray.push([key]);
}
}
}
}
}
return pathArray;
}
Good Luck...
I found the following solution on github.
https://github.com/mariocasciaro/object-path
I believe that the sole existence of the topic linked in the question is originated from string paths in dot notation.
However if in the first place you have to resolve all the paths then you can totally eliminate the string dot notation relieving yourself from unnecessary work.
Assuming that your schema is in the form of
const obj = { name: "somename", personal: { weight: "150", color: "dark" }};
then it would be ideal to collect the paths in an array like
const paths = [["name"], ["personal","weight"], ["personal","color"]]
so that obtaining any nested value is now a piece of cake. Like;
paths[1].reduce((value,path) => value[path], obj); // 150
Let's see in action.
function keyPaths(schema, ...keys){
return Object.keys(schema)
.reduce( (r,k) => ( typeof schema[k] === "object" ? r.push(...keyPaths(schema[k],...keys,k))
: r.push([...keys,k])
, r
)
, []
);
}
const obj = { name: "somename", personal: { weight: "150", color: "dark" }},
paths = keyPaths(obj),
result = paths[1].reduce((value,path) => value[path], obj);
console.log(JSON.stringify(paths,""));
console.log(result);
personal.weight
if your result will have all other properties? – DontVoteMeDown Commented Aug 21, 2015 at 13:22deep_value
, actually? – DontVoteMeDown Commented Aug 21, 2015 at 13:35