patternjavascriptMinor
Is this a good algorithm to unflat js objects?
Viewed 0 times
thisunflatobjectsalgorithmgood
Problem
I am dealing with a scenario where I get data in the following form:
So in order to validate and persist this data I decided to create a way to unflat these strings into regular JS objects, and send them to MongoDb (since it is schema-less).
I coded an algorithm that I am unsure that works for most cases so I created a fiddle that seems to be able to deal with an extreme case, full of nested arrays.
Can someone point any week point or case in which my algorithm would fail? Any kind of advice will be appreciated.
Link to the fiddle here!
Heres the code, where
var data = {
'user.name': 'renatoargh',
'user.age': 27,
'user.interests.0.description': 'coding',
'user.interests.0.receiveNotifications': true,
'user.interests.1.description': 'bungee jumping',
'user.interests.1.receiveNotifications': false
};So in order to validate and persist this data I decided to create a way to unflat these strings into regular JS objects, and send them to MongoDb (since it is schema-less).
I coded an algorithm that I am unsure that works for most cases so I created a fiddle that seems to be able to deal with an extreme case, full of nested arrays.
Can someone point any week point or case in which my algorithm would fail? Any kind of advice will be appreciated.
Link to the fiddle here!
Heres the code, where
messageObject is the array and the output is in messageTreefunction forEachOwnProperty(object, iterator) {
for(var property in object){
if(object.hasOwnProperty(property)) {
iterator(property, object[property]);
}
}
}
forEachOwnProperty(messageObject, function(property, messages) {
property = property.split('.');
var currentNode = messageTree;
for(var i = 0; i < property.length; i++) {
var currentProperty = property[i];
if(typeof currentNode[currentProperty] === 'undefined') {
if(i === property.length - 1) {
currentNode[currentProperty] = messages
} else {
if(/^\+?(0|[1-9]\d*)$/.test(property[i + 1])) {
currentNode[currentProperty] = [];
} else {
currentNode[currentProperty] = {};
}
}
}
currentNode = currentNode[currentProperty];
}
});Solution
Nice code!
-
You should point out assumptions in a comment. You could document, for instance, that if the first encountered subproperty of a property is numeric, it's treated as an array.
-
I would rename
-
Right now, your code won't work with direct arrays. The following
-
There are some very specific edge cases:
-
Finally, just for fun, you can use something like
-
You should point out assumptions in a comment. You could document, for instance, that if the first encountered subproperty of a property is numeric, it's treated as an array.
-
I would rename
messages to something like value. property is fine, but you could also consider key.-
Right now, your code won't work with direct arrays. The following
messageObject won't produce the expected result:messageObject = {
'array.0': 'Code',
'array.1': 'Review'
};-
There are some very specific edge cases:
messageObject = { 'constructor.name': 'renatoargh' } will return an empty object. I'm not really sure what can be done about this though...-
Finally, just for fun, you can use something like
var key = property.splice(-1); to eliminate the second if in your for loop. Of course, after the loop, you'd have to add currentNode[key] = messages;.Code Snippets
messageObject = {
'array.0': 'Code',
'array.1': 'Review'
};Context
StackExchange Code Review Q#59162, answer score: 3
Revisions (0)
No revisions yet.