I have the following to run that for each array index, it will return the sum of the values at that index. For example:
function unnest(elem) {
if (!Array.isArray(elem)) {
return elem;
} else {
return elem.flatMap(e => unnest(e));
}
}
let n = [1,[2,3], [4,[5,6]], 7];
let nx = new Array(n.length);
for (let [idx, elem] of Object.entries(n)) {
if (Array.isArray(elem)) {
// const flatMapR = e => Array.isArray(e) ? flatMapR(e) : e;
let flatArr = unnest(elem);
let sum = flatArr.reduce((x,y) => x+y);
nx[idx] = sum;
} else {
nx[idx] = elem;
}
}
console.log(nx);
// [ 1, 5, 15, 7 ]
Is there a way to replace the unnest function with an arrow function, such as I'm trying to do in the commented code above? If I uncomment that it gives me a recursion error, so I'm guessing maybe an arrow function cannot refer to itself.
Yes, it's easy enough to replace that with a single-statement arrow function, and then map a sum over the results of mapping it to our values. Just use a conditional expression (ternary). I'm assuming that this is what you meant, as it's trivial to replace your original function declaration (function unnest(elem) { ... }) with the equivalent arrow (const unnest = (elem) => {...}). This is entirely mechanical, with only a minor tweak for async functions. It's not available for generator functions, though, or for methods inside class declarations.
It might look like this:
const unnest = (elem) => Array .isArray (elem) ? elem .flatMap (unnest) : elem
const sum = (ns) => Array .isArray (ns) ? ns .reduce ((a, b) => a + b, 0) : ns
const n = [1, [2, 3], [4, [5, 6]], 7]
console .log (n .map (unnest))
console .log (n .map (unnest) .map (sum))
.as-console-wrapper {max-height: 100% !important; top: 0}
However, that requires an odd implementation of sum. I would rather flatten the outer list into an array of (flat) arrays, and then apply a more normal sum to each, like this:
const unnest = (elem) => Array .isArray (elem) ? elem .flatMap (unnest) : [elem]
const sum = (ns) => ns .reduce ((a, b) => a + b, 0)
const n = [1, [2, 3], [4, [5, 6]], 7]
console .log (n .map (unnest))
console .log (n .map (unnest) .map (sum))
.as-console-wrapper {max-height: 100% !important; top: 0}
The only difference in the unnest functions is in how they handle a scalar value. The first one returns it as is, the second one wraps it in an array. I find this more consistent data structure much easier to work with.
Yes you can do this. It's almost unreadable, but here would be the faithful conversion of the function to the arrow expression:
let n = [1,[2,3], [4,[5,6]], 7];
let nx = new Array(n.length);
for (let [idx, elem] of Object.entries(n)) {
if (Array.isArray(elem)) {
const flatMapR = elem => !Array.isArray(elem) ? elem : elem.flatMap(e => flatMapR(e));
let flatArr = flatMapR(elem);
let sum = flatArr.reduce((x,y) => x+y);
nx[idx] = sum;
} else {
nx[idx] = elem;
}
}
console.log(nx);
// [ 1, 5, 15, 7 ]