Skip to content

Instantly share code, notes, and snippets.

@Sequoia
Created June 1, 2016 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sequoia/e4645e07864bcd6be7cb54b9afa900d7 to your computer and use it in GitHub Desktop.
Save Sequoia/e4645e07864bcd6be7cb54b9afa900d7 to your computer and use it in GitHub Desktop.
tool to run different functions based on the type of an object

I'm working with Leaflet.js & Leaflet-Editable.js there are a lot places where I need to respond to clicks on, creation of, etc. different types of map features differently. This function allows me to eschew if,else,if,else blocks for these cases.

Example:

Before

if(is(L.Marker, feature)){
  setMarkerStyleActive(feature);
} else if(is(L.Polyline, feature)){
  setPolylineStyleActive(feature);
} else if(is(L.Polygon, feature)){
  setPolygonStyleActive(feature);
} 

After

const setStyleActive = runByType(new Map([
  [L.Marker, setMarkerStyleActive],
  [L.Polyline, setPolylineStyleActive],
  [L.Polygon, setPolygonStyleActive]
]);

//then when I need to use it
setStyleActive(thing);

not super useful if you only have 1 switch like above but with many it becomes useful

const fnsByType = new Map([
[String, string => string.toUpperCase()],
[Number, num => Math.floor(Math.abs(num))]
]);
stringOrNumberChanger = runByType(fnsByType);
console.log(stringOrNumberChanger("Hello"));
console.log(stringOrNumberChanger(-27.673));
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.getAge = function(){ return this.age; };
const p = new Person("Sequoia", 101);
fnsByType.set(Person, person => `person is ${person.getAge()} years old`);
//now our map can handle a new type
console.log(stringOrNumberChanger(p));
//from ramda https://github.com/ramda/ramda/blob/master/src/is.js
function is(Ctor, val) {
return val != null && val.constructor === Ctor || val instanceof Ctor;
}
/**
* Runs a different function depending on a map of constructors
* to constructors for those functions
*
* @param {Map<Function, Function>} typeToFnsMap - Constructor, fnToRunOnThatType
* @return {Function}
*/
export function runByType(typeToFnsMap){
/**
* @param {any} thing
* @return {any}
*/
return function(thing){
let funToRun = () => new Error('type not supported');
typeToFnsMap.forEach(function(fn, Ctor){
if(is(Ctor, thing)){
funToRun = fn;
return;
}
});
return funToRun(thing);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment