Here's a simple recursive implementation -
// None : symbol
const None =
Symbol()
// zipMap : ('k array, 'v array) -> ('k, 'v) object
const zipMap = ([ k = None, ...keys ] = [], [ v = None, ...values ] = []) =>
k === None || v === None
? {}
: { [k]: v, ...zipMap(keys, values) }
console.log(zipMap([ 1, 2, 3 ], [ 4, 5, 6 ]))
// { 1: 4, 2: 5, 3: 6 }
But it's not much of a "mapping" function; it always returns an Object. What if you wanted a different result?
// None : symbol
const None =
Symbol()
// identity : 'a -> 'a
const identity = x =>
x
// zipMap : (('k, 'v) -> ('kk, 'vv), 'k array, 'v array) -> ('kk, 'vv) array
const zipMap =
( f = identity // ('k, v') -> ('kk, 'vv)
, [ k = None, ...keys ] = [] // 'k array
, [ v = None, ...values ] = [] // 'v array
) => // ('kk, 'vv) array
k === None || v === None
? []
: [ f ([ k, v ]), ...zipMap(f, keys, values) ]
// result : (number, number) array
const result =
zipMap
( identity
, [ 1, 2, 3 ]
, [ 4, 5, 6 ]
)
console.log(result)
// [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
console.log(Object.fromEntries(result))
// { 1: 4, 2: 5, 3: 6 }
// result2 : (number, number) array
const result2 =
zipMap
( ([ k, v ]) => [ k * 10, v * 100 ]
, [ 1, 2, 3 ]
, [ 4, 5, 6 ]
)
console.log(Object.fromEntries(result2))
// { 10: 400, 20: 500, 30: 600 }
Instead of creating an Object using Object.fromEntries
, you could just as easily create a Map
too -
// result2 : (number, number) array
const result2 =
zipMap
( ([ k, v ]) => [ k * 10, v * 100 ]
, [ 1, 2, 3 ]
, [ 4, 5, 6 ]
)
// m : (number, number) map
const m =
new Map(result2)
// Map { 10 => 400, 20 => 500, 30 => 600 }