Reputation: 105547
I have the following object:
var ob = {
view: {
name: 'zpo',
params: {
taskId: 3,
zuka: 'v'
}
}
}
I need to have this object in the following form:
{
"view.name":"zpo",
"view.params.taskId":3,
"view.params.zuka":"v"
}
I have written a function that can do that, but the problem is that it requires external variables passed to it. Here is this function:
function inline(o, result, container) {
for (var p in o) {
if (typeof o[p] === "object") {
inline(o[p], result.length > 0 ? result+'.'+p : p, container);
} else {
container[result + '.' + p] = o[p];
}
}
}
var ob = {
view: {
name: 'zpo',
params: {
taskId: 3,
zuka: 'v'
}
}
}
var c = {};
var r = inline(ob, '', c);
Is there any way to write this function to return correct result without the need to pass result
and container
external variables?
Upvotes: 3
Views: 77
Reputation: 7887
Here is a version that does not require any parameters.
// Return an array containing the [key, value] couples of an object.
const objEntries = o => Object.keys(o).map(k => [k, o[k]]);
// Create an object from an array of [key, value] couples.
const entriesObj = (entries, init={}) => entries.reduce((result, [key, val]) => {
result[key] = val;
return result;
}, init);
// Reduce on the object entries (as returned by objEntries) with an empty object as
// initialiser.
const inline = (o) => objEntries(o).reduce((result, [key, val]) => {
if(val instanceof Object){
// If the value is an object, recursively inline it.
const inlineVal = inline(val);
// Prefix each property names of inlineVal with the key of val and add the
// properties to the result object.
entriesObj(
objEntries(inlineVal).map(([subK, subVal]) => [key + '.' + subK, subVal]),
result
);
} else {
// If val is not an object, just add it to the result as is.
result[key] = val;
}
// Return the result.
return result;
}, {});
var ob = {
view: {
name: 'zpo',
params: {
taskId: 3,
zuka: 'v'
}
}
}
var r = inline(ob);
console.log(r);
I used arrow functions and destructuring. Old browsers won't support it. If you need to support them, just replace the arrow functions with regular functions and manually destructure the arguments.
Upvotes: 0
Reputation: 419
javascript is awesome!
function inline(o, result, container) {
result = result || '';
container = container || {};
for (var p in o) {
if (typeof o[p] === "object") {
inline(o[p], result.length > 0 ? result+'.'+p : p, container);
} else {
container[result + '.' + p] = o[p];
}
}
}
var r = inline(ob);
Upvotes: 0
Reputation: 8165
If i understood you correctly, you want to avoid to call your inline()
function with "empty" params.
You could catch this case in your function directly:
function inline(o, result, container) {
result = result || '';
container = container || {};
...
}
var r = inline(ob);
you would still need this params for the recursive part of your function.
Upvotes: 1