Reputation: 13
Given the following javascript object structure, which is typically what is returned by firebase
var data = {
'id1' : {
'fname' : 'value',
'lname' : 'value',
'things' : {
'thing1' : {
'brand' : 'value',
'name' : 'value'
},
'thing2' : {
'brand' : 'value',
'name' : 'value'
},
'thing3' : {
'brand' : 'value',
'name' : 'value'
}
}
},
'id2' : {
'fname' : 'value',
'lname' : 'value',
'things' : {
'thing1' : {
'brand' : 'value',
'name' : 'value'
},
'thing2' : {
'brand' : 'value',
'name' : 'value'
},
'thing3' : {
'brand' : 'value',
'name' : 'value'
}
}
}
};
How would you convert it to
[
{
'fname' : 'value',
'lname' : 'value,
'things' : [
{
'brand' : 'value',
'name' : 'value'
},
{
'brand' : 'value',
'name' : 'value'
},
{
'brand' : 'value',
'name' : 'value'
}
]
},
{
'fname' : 'value',
'lname' : 'value,
'things' : [
{
'brand' : 'value',
'name' : 'value'
},
{
'brand' : 'value',
'name' : 'value'
},
{
'brand' : 'value',
'name' : 'value'
}
]
}
]
Keeping in mind that the nested objects could get deeper than this. There are many implementations to convert nested structures to arrays, but I have not seen anyone make this specific conversion. I've been racking my brain for a while and have only come very close but have yet to get it just right.
I already have this code which doesn't do anything with deeper objects like 'things'.
var collection = [];
for(key in data) {
collection.push(data[key]);
}
I'm struggling with making it recursive.
EDIT I would imagine it needs to be in wrapped in a function that can call itself so that it can be made recursive.
Upvotes: 1
Views: 132
Reputation: 36
Here's a solution that doesn't require knowing the keys, assuming that you want to convert every other level of nesting:
function toArrayOfObjects(obj) {
var collection = [];
for (key in obj) {
var value = obj[key];
if (typeof value === 'object' && !Array.isArray(value)) {
var childObj = {};
for (childKey in value) {
var childValue = value[childKey];
if (typeof childValue === 'object' && !Array.isArray(childValue)) {
childObj[childKey] = toArrayOfObjects(childValue);
} else {
childObj[childKey] = childValue;
}
}
collection.push(childObj);
} else {
collection.push(value);
}
}
return collection;
}
Upvotes: 2
Reputation: 598728
Something like this should do the trick:
function convert(object, propNamesToConvert) {
var array = [];
Object.keys(object).forEach(function(key) {
array.push(visit(object[key], propNamesToConvert));
});
return array;
}
function visit(object, propNamesToConvert) {
var result = {};
Object.keys(object).forEach(function(key) {
var value = object[key];
if (typeof(value) === 'object') {
// objects are either 'things to be converted' or we need to traverse further down the rabbit hole
if (propNamesToConvert.indexOf(key) >= 0) {
value = convert(value, propNamesToConvert);
}
else {
value = visit(value, propNamesToConvert);
}
}
result[key] = value;
});
return result;
}
console.log(JSON.stringify(visit(data, ['things'])));
It could probably be shortened considerably, but this works. It would be way better to translate the hard-coded ['things']
into something that is less maintenance-prone.
var data = {
'id1' : {
'fname' : 'value',
'lname' : 'value',
'things' : {
'thing1' : {
'brand' : 'value',
'name' : 'value'
},
'thing2' : {
'brand' : 'value',
'name' : 'value'
},
'thing3' : {
'brand' : 'value',
'name' : 'value'
}
}
},
'id2' : {
'fname' : 'value',
'lname' : 'value',
'things' : {
'thing1' : {
'brand' : 'value',
'name' : 'value'
},
'thing2' : {
'brand' : 'value',
'name' : 'value'
},
'thing3' : {
'brand' : 'value',
'name' : 'value'
}
}
}
};
function convert(object, propNamesToConvert) {
var array = [];
Object.keys(object).forEach(function(key) {
array.push(visit(object[key], propNamesToConvert));
});
return array;
}
function visit(object, propNamesToConvert) {
var result = {};
Object.keys(object).forEach(function(key) {
var value = object[key];
if (typeof(value) === 'object') {
if (propNamesToConvert.indexOf(key) >= 0) {
value = convert(value, propNamesToConvert);
}
else {
value = visit(value, propNamesToConvert);
}
}
result[key] = value;
});
return result;
}
console.log(JSON.stringify(visit(data, ['things'])));
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
Upvotes: 1
Reputation: 1958
var newData = [];
var dataKeys = Object.keys(data);
for(var i=0; i<dataKeys.length; i++)
{
newData.push(data[dataKeys[i]]);
}
Upvotes: 0