Got an array with functions. I want to do a function that returns a function from the array with function name given as argument.
var arr = [
function Dog(){},
function Cat(){}
];
var getFunction = function(name){
return // should return the function with matching name
};
var dogFunction = getFunction('Dog'); // returns dog function.
https://jsfiddle.net/zcjd9pyz/
Is this possible?
5 Answers 5
if you do an associative array, it is possible
var arr = {
'dog' : function Dog(){},
'cat' : function Cat(){}
};
arr['dog']();
4 Comments
var myFcuntion = arr['functionName'];Functions have a name property:
var getFunction = function(name){
for (var i=0; i<arr.length; i++) {
if (arr[i].name===name) return arr[i];
}
return // return undefined
};
If you want to have a fast access, you can precompute a map by first iterating:
var map = arr.reduce(function(m,f){ m[f.name]=f; return m}, {});
which allows
var fun = map["Dog"];
Computing the map in code instead of typing it yourself lets you not repeat the name. A DRY code is easier to maintain.
EDIT: I'm not sure functions have a name on IE but I can't test it.
6 Comments
name function property is not supported in Internet Explorer. You could polyfill it by extracting the function's name from the value returned by toString()In ES6 you could do it without modifying the array (or in all browsers except Internet Explorer if you replace the arrow function with a normal one and use a polyfill for find:
var getFunction = function(name){
return arr.find( func => name === func.name );
};
Even in ES6 though, I don't see a good reason to do that. I think you should follow Deblaton Jean-Philippe's answer and change the array to an object, mapping the names to the functions.
You can use this sample work around of mine, instead of matching for string you can use it based on function name
https://gist.github.com/freewayz/56bd9db6d4164a42be75
var myArray = [{"name" : "pitaside", "id" : 1}, {"name":"github", "id" : 3}]
filterArrayByType: function (arrayToMatch, fieldType, matcher) {
if(! arrayToMatch instanceof Array){throw ("Not an Array")}
var filterTypeToReturn = arrayToMatch.filter((items) => {
var temp;
if (items[String(fieldType)] === matcher) {
temp = items[String(fieldType)]
}
return temp;
}
);
return filterTypeToReturn;
}
var myMatcher = 'github'
var id3 = filterArrayByType(myArray, 'name', myMatcher)[0].id
//returns 3
Comments
You can use Function.prototype.toString(). Unlike name it is supported by most of the modern browsers as well as by Node.js.
var arr = [
function Dog ( ) {},
function Cat ( ) {}
];
var getFunction = function(name){
'use strict';
// could use find but it isn't supported by IE
return arr.filter(function (func) {
return /^function\s+(\w+)/.exec(func.toString())[1] === name;
})[0];
};
console.log(getFunction('Dog'));
console.log(getFunction('Cat'));
console.log(getFunction('Unknown'));