Вот еще одно рекурсивное решение, немного отличающееся от ответа Нины Шольц.У него есть функция, позволяющая точно выбирать n
элементов из списка, а затем она используется в основной функции, которая вызывает его для каждого значения от min
до max
:
const choose = (n, xs) =>
n < 1 || n > xs .length
? []
: n == 1
? [...xs .map (x => [x])]
: [
...choose (n - 1, xs .slice (1)) .map (ys => [xs [0], ...ys]),
...choose (n , xs .slice (1))
]
const getCombs = (min, max, xs) =>
xs .length == 0 || min > max
? []
: [...choose (min, xs), ...getCombs (min + 1, max, xs)]
console .log (
getCombs (0, 3, [1, 2, 3]),
getCombs (2, 2, [1, 2, 3])
)
Здесь getCombs
- основная функция, и она должна быть достаточно ясной, просто конкатенируя результат choose (min, xs)
с результатом рекурсивного вызова getCombs (min + 1, max, xs)
.choose
- это многократно используемая функция, которая работает с двойной рекурсией: первая выбирает все те комбинации, которые используют исходный элемент, а вторая - те, которые не используют.
Это не совсем соответствует Нинерешение, так как игнорирует пустой список, когда min
равен нулю.Если вам нужен список с пустым списком, вы можете изменить choose
на (немного уродливее, ИМХО) версию:
const choose = (n, xs) =>
n < 1 || n > xs .length
? [[]]
: [
...choose (n - 1, xs .slice (1)) .map (ys => [xs [0], ...ys]),
...(n + 1 > xs .length ? [] : choose (n , xs .slice (1)))
]