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