Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get every possible combination of elements

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

like image 678
sa555 Avatar asked Feb 28 '16 20:02

sa555


People also ask

How do you find all possible combinations?

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.

How many combinations are possible with 5 items?

So we say that there are 5 factorial = 5! = 5x4x3x2x1 = 120 ways to arrange five objects.


2 Answers

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]]
like image 95
davidchambers Avatar answered Sep 27 '22 23:09

davidchambers


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)
like image 31
homam Avatar answered Sep 27 '22 23:09

homam