Reputation: 32912
I would like to create permutations over Set(0..n) in Javascript.
I am struggling with Array methods: some of them like map
return a new array that could be further modified, others like forEach
does not. To encode permutations, I could do it only with enhancing Array prototype:
Object.defineProperty(Array.prototype, "chain", {
value: function(method, arg) {
this[method].call(this, arg);
return this;
}
});
Object.defineProperty(Array.prototype, "value", {
value: value => value // to value value ;-)
});
Only then I was able to encode permutations:
let perm = (n) =>
n==0 ? [[0]] :
perm(n-1).reduce((acc, cur) =>
cur.chain("forEach", (_, i) =>
acc.chain("push", [...cur.slice(0,i), n, ...cur.slice(i)])
).value(acc).chain("push", [...cur,n])
,[])
Test:
console.log(perm(2));
So is it feasible in ES6 (without adding to Array prototype) to encode permutations over Set (or any Array-like object) in pure functional way?
I don't want to rape Javascript (like jQuery did back then) to force it some non-native paradigm, but I'd like to fully understand its potential on the functional field.
Upvotes: 1
Views: 78
Reputation: 664548
No ES6 needed at all. You should not use forEach
or push
if you want to program in a functional style - and hiding them in a chain
method so that you can write expressions with useful return values doesn't help.
Instead, all you want are map
and concat
:
let perm = (n) =>
n==0 ? [[0]] :
perm(n-1).reduce((acc, cur) =>
acc.concat(cur.map((_, i) =>
[...cur.slice(0,i), n, ...cur.slice(i)]
), [[...cur,n]])
, [])
Of course you could also replace the concat
call by array spread syntax if you're inclined.
Upvotes: 3