JavaScript: Assign value to object from string
Introduction and disclaimer
Some time back I found myself in need of a way to take a string from dot notation contacts.name.first
and build/update an object from that.
I scoured the internet and found several methods, none of which quite did what I needed them to do; some would only update an existing object, while others would only create a new object. Most only worked down to a handful of levels.
I took what I found and used them as a reference to create this handy method. Very little of this method is purely my brainchild, but rather a combination of help from the geniuses that troll StackOverflow.
I also want to admit that there are likely other ways to go about this exact same thing, some may even be more elegant.
String toObject
String.prototype.toObject = function( obj, value ) {
var names = this.split('.');
// If a value is given, remove the last name and keep it for later:
var lastName = arguments.length === 2 ? names.pop() : false;
// Walk the hierarchy, creating new objects where needed.
// If the lastName was removed, then the last object is not set yet:
for( var i = 0; i < names.length; i++ ) {
obj = obj[ names[i] ] = obj[ names[i] ] || {};
}
// If a value was given, set it to the last name:
if( lastName ) obj = obj[ lastName ] = value;
// Return the last object in the hierarchy:
return obj;
};
Usage
Using the method is simple. As its an extension of the javascript String
object you mere chain it from the dot notated sting, like so:
var newObject = {};
'contact.name.first'.toObject(newObject, 'Josey');
Which, if you then log newObject
you will get the following:
{
contact: {
name: {
first: 'Josey'
}
}
}
Conclusion
I hope this ends up helping someone else; I've found it immensely useful for things like shortcuts to update data via url query strings.
Written by Josey Morton
Related protips
3 Responses
I know of a couple different ways for this to be useful in some of my projects. Especially working with things like properties files that have a syntax similar to my.little.object=foobar
per line. A couple of tweaks, and this could become very, very useful for that!
I wrote something similar to this for a project just recently. Except instead of creating an object, I'm searching for it within a context. In other words, "Ns.Utilities.MyUtility" would search for "Ns" inside "window" (unless another context was given), "Utilities" inside that result, and finally "MyUtility" inside that result. I have found it very, very useful. I'll see if I can carve out the time to throw it into a tip!
I would be very interested indeed to see your implementation.
Does it create the object if it doesn't exist in the context?
I totally forgot to get back on here after your reply!
But check out my implementation here.
Most specifically:
var my = { little: { object: "foobar" } };
function getObjectFromString(objRef) {
myObj = window;
var refParts = objRef.split('.');
for (var c=0;c<refParts.length;c++) {
var classVar = refParts[c];
if (!classVar || !myObj[classVar]) {
myObj = null;
break;
}
myObj = myObj[classVar];
}
return myObj;
}
var result = getObjectFromString("my.little.object");
console.log(result); // "foobar"
It's not the best implementation in the world, but I wanted to avoid function recursion, so I decided to use a for loop instead that simply sets a variable over and over again. This changes the context and allows you to traverse the dimensions of the object based on the string provided.