DEV Community

loading...

Too clever for your own good?

Bruce Axtens
Programmed Canon Canola calculators in 1977. Assorted platforms and languages ever since. Assisting with HOPL.info. I am NOT looking for work -- I've got more than enough to do.
・2 min read

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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
                }
            ]], "");
Enter fullscreen mode Exit fullscreen mode
let target = selector("page value", [
            ["domain", "domain"],
            ["subdomain", "subdomain"],
            [x => x === "page value" ? "page" : x
            ]], "");
Enter fullscreen mode Exit fullscreen mode

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"));
Enter fullscreen mode Exit fullscreen mode
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");
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (0)