使用 javascript 创建 zipmap 函数?

Create a zipmap function using javascript?

考虑这个问题:

创建一个接受两个序列的函数 zipmap,并创建一个从第一个序列的元素到第二个序列的元素的字典。

zipmap([1, 2, 3], [4, 5, 6]) => {1: 4, 2: 5, 3: 6}

下面是我的解决方案作为答案,谁能想出更好的方法吗?

const R = require('ramda')

const zipmapSeparate = (...arr) => arr[0].map((zeroEntry, index) => {
    const item = {}
    item[arr[0][index]] = arr[1][index]
    return item
})

const zipmapReduce = (zipmap1) => zipmap1.reduce((accumulator, current) => {
    const key = Object.keys(current)[0]
    const value = Object.values(current)[0]
    accumulator[key]=value
    return accumulator
}, {})

const zipmap = R.compose(zipmapReduce, zipmapSeparate)

console.log(zipmap([1, 2, 3], [4, 5, 6]))
const zipmap = (arr1 ,arr2) => arr1.reduce((p,c,i) => {
  p[c] = arr2[i];
  return p;
},{});

这已经内置到 Ramda 中,如 zipObj:

console .log (
  R.zipObj ([1, 2, 3], [4, 5, 6])
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

它现在也是一种语言功能,可能还没有得到足够广泛的支持,但已经接近:Object.fromEntries

这是一个简单的递归实现 -

// 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 }

但这并不是什么 "mapping" 功能;它总是 returns 一个对象。如果您想要不同的结果怎么办?

 
// 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 }

无需使用 Object.fromEntries 创建对象,您也可以轻松创建 Map -

// 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 }