Too clever for your own good?
Bruce Axtens
Posted on October 4, 2019
JavaScript is great for prototyping ideas. Okay, so it's a prototype-based language but we probably mean slightly different things.
I wanted to do a calculated selection of a value and quickly threw together the following, which takes a parameter, compares it to an array of possible match/result pairs, along with a default value in the event that there's no match in the match/result pairs. I also coded in the possibility of embedding a function.
Here's the ES3 code
function selector(target, casevalues, defaultvalue) {
for (var i = 0; i < casevalues.length; i++) {
var caseval = casevalues[i];
if ("string" === typeof caseval[0]) {
if (target === caseval[0]) {
return caseval[1];
}
} else { //assume function
return caseval[0](target);
}
}
return defaultvalue;
}
and the equivalent ES5 code
const selector = (target, casevalues, defaultvalue) => {
for (let i = 0; i < casevalues.length; i++) {
const caseval = casevalues[i];
if ("string" === typeof caseval[0]) {
if (target === caseval[0]) {
return caseval[1];
}
} else { //assume function
return caseval[0](target);
}
}
return defaultvalue;
}
Evaluating that can be done like this (ES3 then ES5):
var target = selector("page value", [
["domain", "domain"],
["subdomain", "subdomain"],
[function (x) {
return x === "page value" ? "page" : x
}
]], "");
let target = selector("page value", [
["domain", "domain"],
["subdomain", "subdomain"],
[x => x === "page value" ? "page" : x
]], "");
So pretty cool, right? We-e-e-ell, maybe not. The whole thing might just as readily be expressed in a shorter piece of code, and done inline, using in-place evaluation. ES3 and ES5:
var target = (function (item) {
switch (item) {
case "page value":
return (function (x) {
return x === "page value" ? "page" : x
}(item));
case "domain":
return "domain";
case "subdomain":
return "subdomain";
}
return "";
}("page value"));
const target = (item => {
switch (item) {
case "page value":
return (x => x === "page value" ? "page" : x)(item);
case "domain":
return "domain";
case "subdomain":
return "subdomain";
}
return "";
})("page value");
Cost-benefit is the key here. Where I was wanting the original selector, the inline worked better and was more efficient. Maybe you do want to have a generalised selector
function, in which case something like the above would work. An improvement might be to pass in an array of key-value-pair objects instead of an array of match/result pairs.
Okay, that's me done with thinking aloud for now. Kudos to Lebab's online editor for helping with the ES3 to ES5 conversions.
Posted on October 4, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.