2

I'm looking for an elegant way to override values in an associative array.

For example, say I have my base options as:

var base_options = {
    hintText:"something",
    borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED,
    width: 200, height: LABEL_HEIGHT-4,
    font: {fontSize:16}, left: 95
}

I want to use this as the base, but be able to override a few items in this base on a case-by-case basis - for example, hintText would be different for each item. What's a clean and elegant way to get a copy of this array with a few parameters modified?

I realize I can change each individual item, as in:

options.hintText = "new thing";

but I suspect there's a more elegant way.

Parand
  • 102,950
  • 48
  • 151
  • 186

6 Answers6

1

You could use a base class to encapsulate the behavior Weston propose.

function Options(changed_options) {
     this.hintText = "something";
     this.borderStyle =Titanium.UI.INPUT_BORDERSTYLE_ROUNDED;
     // ...

     if(changed_options)
         for(var prop in changed_options) 
             this[prop] = changed_options[prop];
}

var foo = new Options({ "hintText":"changed"});

Should work.

Zebi
  • 8,682
  • 1
  • 36
  • 42
  • This is a nice solution because there's a smaller chance of accidentally changing the base object by copying an object reference (in the font property, for example) to the new object. If you want to avoid that with the other solutions, you'd have to create copies of the objects. – Cristian Sanchez Aug 25 '10 at 21:31
0

You could use the object's prototype to establish the inheritance, like this:

function inherited_object(extra_properties){
    for(var i in extra_properties){
        this[i] = extra_properties[i];
    }
}
function inherit_from(parent, extra_properties){
    inherited_object.prototype = parent;
    var obj = new inherited_object(extra_properties || {});
    inherited_object.prototype = null;
    return obj;
}

Then, if you have some object A you just call B = inherit_from(A, B_stuff) and that's it. One advantage is that, because A is the prototype of B, changes done to A are reflected on B.

Giovany
  • 21
  • 1
0

Something like this?

var changed_options = { 
   hintText: "somethingElse",
   font: {fontSize: 24} 
}

for(var prop in changed_options) 
    base_options[prop] = changed_options[prop];
Weston C
  • 3,642
  • 2
  • 25
  • 31
0
function merge(base, options) { 
   var result = {};
   for (var k in base) if (base.hasOwnProperty(k)) {
      result[k] = options[k] || base[k];
   } // note, it will leave out properties that are in options, but not in base..
   return result;
}

If you happen to be using jQuery, it has a built in extend method on the jQuery object that does this.

Cristian Sanchez
  • 31,171
  • 11
  • 57
  • 63
0

I have implemented this function in a few of my projects:

if (typeof Object.merge !== 'function') {
    Object.merge = function (o1, o2) { // Function to merge all of the properties from one object into another
        for(var i in o2) { o1[i] = o2[i]; }
        return o1;
    };
} 

So, now I can use it like:

Object.merge(options, {hintText: "new thing", left: 55});

As far as copying objects, there is already a good StackOverflow discussion about that.

Community
  • 1
  • 1
palswim
  • 11,856
  • 6
  • 53
  • 77
-1
var base_options = function() { 
    hintText:arguments[0], 
    borderStyle:arguments[1], 
    width:arguments[2],
    height:arguments[3], 
    font:arguments[4]
    left:arguments[5]
};

var thisObj = new base_option(blah, blah, blah, blah, blah);

That may seem like overkill but then you can add all of the new instances to an array and use a for loop for them when you want/need to change them.

John
  • 1,530
  • 1
  • 10
  • 19
  • This is **very** fragile code. Referencing arguments by index gets you in problems very fast and it's not especially nice to read. – Zebi Aug 25 '10 at 21:22
  • If your going to downvote and answer please explain why. This will help me not post wrong answers if it is wrong. Thank you. // Sorry @Zebi, my page was slow on the update. – John Aug 25 '10 at 21:24
  • It depends on the coder and thier understanding of the code they are writing. It is no diffirent than writing a for loop using the index to access each property in an array, no? – John Aug 25 '10 at 21:32
  • It's different because if you are using for you can not mismatch properties because the order changed. You can not forget to add a property and finally you don't answer the question asked because you don't merge default values with overridden values. – Zebi Aug 25 '10 at 21:39