How would you get every possible combination of 2 elements in an array?
For example:
[
1,
2,
3,
4
]
becomes
[
[1, 2],
[1, 3],
[1, 4],
[2, 1],
[2, 3],
[2, 4],
[3, 1],
[3, 2],
[3, 4],
[4, 1],
[4, 2],
[4, 3]
]
This answer uses brute force but is there a functional way with Ramda and or currying? Derive every possible combination of elements in array
To calculate combinations, we will use the formula nCr = n! / r! * (n - r)!, where n represents the total number of items, and r represents the number of items being chosen at a time. To calculate a combination, you will need to calculate a factorial.
So we say that there are 5 factorial = 5! = 5x4x3x2x1 = 120 ways to arrange five objects.
Here's an elegant solution:
// permutations :: Number -> [a] -> [[a]]
const permutations = R.compose(R.sequence(R.of), R.flip(R.repeat));
Usage examples:
permutations(2, [1, 2, 3, 4]);
// => [[1, 1], [1, 2], ..., [4, 3], [4, 4]]
permutations(3, [1, 2, 3, 4]);
// => [[1, 1, 1], [1, 1, 2], ..., [4, 4, 3], [4, 4, 4]]
Borrowing from Haskell:
as = [1, 2, 3]
f xs = do
a <- xs
b <- xs
return $ if a == b then [] else [a, b]
main = print $ filter (not . null) . f $ as
This is my Ramda version:
var as = [1, 2, 3, 4]
var f = xs =>
R.pipe(
R.chain(a => R.map(b => a == b ? [] : [a, b])(xs))
, R.filter(R.pipe(R.isEmpty, R.not))
)(xs)
console.log(f(as))
PS. LiveScript has a nice syntax for this: http://homam.github.io/try-livescript/#welcome/lists
For choosing a subset of ant size: Ramda code
var g = (xs, n) =>
n == 0 ? [[]] :
R.isEmpty(xs) ? [] :
R.concat(
R.map(R.prepend(R.head(xs)), g(R.tail(xs), n - 1))
, g(R.tail(xs), n)
)
g(as, 3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With