3

My goal is to efficiently apply a dynamically chosen set of transforms to each element of a matrix. I store the selected functions in an array, then apply each of them in a single pass thru the matrix.

My question is, how can I dynamically create the name of a function that I add to the array of functions?

This fiddle contains my attempt. My question is included in the comment block.

function dynam () {
 var prepend = 'before - ';
 var append = ' - after';
 var whichCase = 'Upper';
 var functionsToApply = [];
 var matrix = [
 ['aBc', 'DeF'],
 ['ghi', 'JKL'],
 ];
 var out = 'Initial: ' + matrix.join(' | ');
 document.getElementById('output').innerHTML = out + '\n';
 console.log(out);
 // Set up transforms
 if (whichCase == 'Lower') {
 functionsToApply.push(function(v) {return v.toLowerCase();});
 } else if (whichCase == 'Upper'){
 functionsToApply.push(function(v) {return v.toUpperCase();});
 }
// How can the function be defined dynamically?
// Perhaps something like:
// if(['Lower','Upper'].indexOf(whichCase) != -1) {
// functionsToApply.push(function(v) {'return v.to' + which + 'Case();'});
// }
 if (prepend && prepend.length > 0 && prepend != 'none') {
 functionsToApply.push(function(v) {return prepend + v;});
 }
 if (append && append.length > 0 && append != 'none') {
 functionsToApply.push(function(v) {return v + append;});
 }
// Apply all of the transforms to each of the elements of the matrix
 matrix = matrix.map(function(row){
 return row.map(function(val) {
 for (var fn = 0; fn < functionsToApply.length; fn++) {
 val = functionsToApply[fn](val); 
 }
 return val;
 })
 }); 
 out = 'Final: ' + matrix.join(' | ');
 document.getElementById('output').innerHTML += out + '\n';
 console.log(out);
}

1 Answer 1

2

I like to declare my functions in a hash in this case, then you can call them based on the value passed in, which is the key to the hash.

Updated: I've added a way to get the lower/upper function dynamically, and call it.

function dynam(whichCase, prepend, append, matrix) {
 var functionHash = {
 "Lower" : function(v) {return v.toLowerCase();},
 "Upper" : function(v) {return v.toUpperCase();},
 "Prepend" : function(v) {return prepend + v;},
 "Append": function(v) {return v + append;}
 }
// to actually get the case function based on the word passed in, 
// you can do it this way.
 var lowerUpperFunction = String.prototype['to' + whichCase + 'Case'];
 var str = lowerUpperFunction.call("xyz");
 console.log(str);
 var functionsToApply = [];
 
 var out = 'Initial: ' + matrix.join(' | ');
 console.log(out);
 
 // see how we just take the whichCase and make that a call to the hash?
 functionsToApply.push(functionHash[whichCase]);
if (prepend && prepend.length > 0 && prepend != 'none') {
 functionsToApply.push(functionHash["Prepend"]);
 }
if (append && append.length > 0 && append != 'none') {
 functionsToApply.push(functionHash["Append"]);
}
// Apply all of the transforms to each of the elements of the matrix
 matrix = matrix.map(function(row){
 return row.map(function(val) {
 for (var fn = 0; fn < functionsToApply.length; fn++) {
 console.log("applying function to val" + val );
 val = functionsToApply[fn](val); 
 }
 return val;
 })
 }); 
 out = 'Final: ' + matrix.join(' | ');
 return out;
}
 var p = 'before - ';
 var a = ' - after';
 var w = 'Upper';
 var m = [
 ['aBc', 'DeF'],
 ['ghi', 'JKL'],
 ];
 
 console.log( dynam(w, p, a, m) );

answered Apr 6, 2017 at 0:28
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. While I appreciate the effectiveness of this solution, I'm still wondering if there is a way to use text concatenation to actually create the function name.
I've added what you want there. Basically, you concatenate the name into the String.prototype like this: var lowerUpperFunction = String.prototype['to' + whichCase + 'Case']; and call it like this: var str = lowerUpperFunction.call("xyz");
Thank you, nixkuroi. That looks like what I was trying for. It's late now, so I'll play with it tomorrow. I appreciate your help!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.