4
\$\begingroup\$

Though I can achieve most ends via a series of conditionals and arithmetic, especially when iterating over or comparing arrays I frequently hear of much more efficient implementations.

Hailing from PHP, I am accustomed to having array_merge() accessible; this JS function is different in that key that don't match the first array should be discarded (and generally, I'm using this sort of thing as a way of generating config objects for various parameterized components of a larger project).

I was hoping a serious comp-sci nerd could comment to the efficiency of this implementation of the same in JavaScript, and if it can be improved, explain—even very briefly—what's happening, computationally as it were. I have the intuitive sense that there it a bit-wise operation that could achieve this faster:

function mapConfig(template, cfg) {
    var configured_template = {};
    for (key in cfg) {
        template[key] = key in template ?  cfg[key] : false;
    }
    return template
}

var template = {key1:false, key2:false, key3:false};
var cfg = {key1:true, keyTWO:"puppies", key3:false};

var cfg_obj = mapConfig(template, cfg);
console.log(cfg_obj);

//output >>> {key1:true, key2:false, key3:false}

I appreciate any insights anyone could offer.

\$\endgroup\$
  • \$\begingroup\$ What is forbid_flags in your function? I don't see it defined anywhere and why not just use an if statement if there's only one arm to your conditional? \$\endgroup\$ – jfriend00 May 14 '14 at 22:59
  • \$\begingroup\$ Oh man, so sorry; I'd meant to generify this for the web and somehow I brain-farted and left a lot of my context-dependent vars in, so confusing. Apologies, there. \$\endgroup\$ – Jonline May 14 '14 at 23:24
  • \$\begingroup\$ Also, what should configured_template do ? \$\endgroup\$ – konijn May 15 '14 at 12:14
3
\$\begingroup\$

Interesting question,

there is no faster approach that I know of, in essence, your approach mimics jQuery's $.extend() source code. Except that your code does not clone parameters which might bring you trouble.

I think your code might be messed up, or you might not understand what it is doing.

This:

var template = {key1:false, key2:false, key3:false};
var cfg = {key1:true, keyTWO:"puppies", key3:false};

var cfg_obj = mapConfig(template, cfg);
console.log(cfg_obj);

is equivalent to this:

var template = {key1:false, key2:false, key3:false};
var cfg = {key1:true, keyTWO:"puppies", key3:false};

mapConfig(template, cfg);
console.log(template);

because you change the provided object itself, which probably is not right in all circumstances. I assume that is why you have configured_template in there ?

Furthermore, it does not seem to make sense to assign false to properties that you want to discard.. It eats up memory for no good reason.

All in all, I would counter propose

function configureTemplate( template, config) {
    var result = {}, key;
    for (key in config) {
        if( key in template ){
          result[key] = config[key];
        }
    }
    return result;
}

Note that you were polluting the global namespace by not declaring key with var.

Personally, I would drop most of the curly braces:

function configureTemplate( template, config) {
    var result = {}, key;
    for (key in config)
        if( key in template )
          result[key] = config[key];
    return result;
}

var template = {key1:false, key2:false, key3:false};
var cfg = {key1:true, keyTWO:"puppies", key3:false};

var cfg_obj = configureTemplate(template, cfg);
console.log(cfg_obj);

On a final note, try not to disemvowel your variables. It makes grokking code needlessly harder.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.