Вот один из способов сделать это с помощью рекурсии -
const None =
Symbol ()
const roundRobin = ([ a = None, ...rest ]) =>
// base: no `a`
a === None
? []
// inductive: some `a`
: isEmpty (a)
? roundRobin (rest)
// inductive: some non-empty `a`
: [ head (a), ...roundRobin ([ ...rest, tail (a) ]) ]
Работает в разных случаях -
const data =
[ [ 1 , 4 , 7 , 9 ]
, [ 2 , 5 ]
, [ 3 , 6 , 8 , 10 , 11 , 12 ]
]
console.log (roundRobin (data))
// => [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ]
console.log (roundRobin ([ [ 1 , 2 , 3 ] ]))
// => [ 1 , 2 , 3 ]
console.log (roundRobin ([]))
// => []
Свободные переменные определяются с использованием префиксной нотации, которая более знакомас функциональным стилем -
const isEmpty = xs =>
xs.length === 0
const head = xs =>
xs [0]
const tail = xs =>
xs .slice (1)
Убедитесь, что он работает в вашем браузере ниже -
const None =
Symbol ()
const roundRobin = ([ a = None, ...rest ]) =>
a === None
? []
: isEmpty (a)
? roundRobin (rest)
: [ head (a), ...roundRobin ([ ...rest, tail (a) ]) ]
const isEmpty = xs =>
xs.length === 0
const head = xs =>
xs [0]
const tail = xs =>
xs .slice (1)
const data =
[ [ 1 , 4 , 7 , 9 ]
, [ 2 , 5 ]
, [ 3 , 6 , 8 , 10 , 11 , 12 ]
]
console.log (roundRobin (data))
// => [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ]
console.log (roundRobin ([ [ 1 , 2 , 3 ] ]))
// => [ 1 , 2 , 3 ]
console.log (roundRobin ([]))
// => []
Вот еще один способ использования вторичного параметра с назначением по умолчанию -
const roundRobin = ([ a = None, ...rest ], acc = []) =>
// no `a`
a === None
? acc
// some `a`
: isEmpty (a)
? roundRobin (rest, acc)
// some non-empty `a`
: roundRobin
( append (rest, tail (a))
, append (acc, head (a))
)
const append = (xs, x) =>
xs .concat ([ x ])