-1
\$\begingroup\$

Oftentimes my JavaScript/TypeScript code becomes riddled with annoying code flow structures like below. Is there a way to do concise [functional] one-liners without being messy?

Input:

const objL = [{foo: true, can: undefined, bar: null, arr: []}];

Throughput:

objL[0] = Object.keys(objL[0]).map(k => (
    {[k]: objL[0][k] != null ? objL[0][k] : false}
)).reduce((a, b) => Object.assign(a, b), {});

Output [expectation]:

assert.deepEquals(objL, [{foo: true, can: false, bar: false, arr: []}]);
\$\endgroup\$
  • \$\begingroup\$ no there is not. in programming "concise" and "clean" are usually opposites. Either keep golfing it or break it up and make it readable. you can't it both ways. at least not with the example you gave. \$\endgroup\$ – I wrestled a bear once. Jun 29 '17 at 11:08
  • 3
    \$\begingroup\$ You might be able to simplify a bit: objL[0] = Object.entries(objL[0]).reduce((result, [key, value]) => { result[key] = value != null ? value : false; return result; }, {}) \$\endgroup\$ – le_m Jun 29 '17 at 16:49
  • 1
    \$\begingroup\$ @200_success: It's not so much about the specific problem I'm solving, but about: code flow, functional programming, and structure. TypeScript is referenced insofar as its transpilation ability, so that ES# features are supported and immediately useable without a second-thought. \$\endgroup\$ – A T Jun 30 '17 at 10:33
  • 2
    \$\begingroup\$ Code Review is here to review your code — real code that accomplishes a specific task — not to give you general programming advice based on extrapolation from a tiny sample. \$\endgroup\$ – 200_success Jun 30 '17 at 10:36
  • 1
    \$\begingroup\$ @IgorSoloydenko Please edit the question to bring it up to site standards, then. \$\endgroup\$ – 200_success Dec 29 '17 at 1:06
1
\$\begingroup\$

Functional libraries, namely Ramda and Lodash, can map over an object:

R.map(val => val == null ? false : val, objL[0])

You still need to assign the result to something though, as this function is non-mutating.

\$\endgroup\$
0
\$\begingroup\$

I think, the key is in not fighting the complexity in-place, but rather move it out.

If the language does not provide a construction you need, you can try using a library (like lodash; I'm not sure if it has what you need).

If you don't want to use any third-party dependencies, you can still home brew the missing thing. It can be as simple as an importable isolated function:

function replaceObjectNullFields(source, nullReplaceValue = false) {
    return Object
        .keys(source)
        .reduce(
            (subResult, key) => (
                subResult[key] = source[key] != null ? source[key] : nullReplaceValue,
                subResult
            ),
            {}
        );
}

Then you don't have the nasty proliferation of the micro-level details across the code base. It's nasty because it forces us mixing the abstractions of different levels...

With the function above you can rewrite the code into a one-liner, because the complexity is encapsulated somewhere else

objL[0] = replaceObjectNullFields(objL[0])


Alternatively, you could write a more generalized mapObject() function with a signature similar to what @Pavlo demonstrated in his good answer.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.