Javascript 哈希表的对象数组

Javascript 哈希表的对象数组,javascript,ramda.js,Javascript,Ramda.js,要转换(使用Ramda) 进入 我对函数式编程非常陌生,我对任何想法都持开放态度 我认为我们必须做的是,使用一个从{}开始的reduce函数,然后我们希望在每次迭代中将当前元素的id和名称添加到哈希表中。这是我提出的,看起来非常错误。我接近了吗 var a = [{id: 1, name: 'one'}, {id: 2, name: 'two'},{id: 3, name: 'three'},{id: 4, name: 'four'} ] var b = R.reduce(R.assoc(R.p

要转换(使用Ramda)

进入

我对函数式编程非常陌生,我对任何想法都持开放态度

我认为我们必须做的是,使用一个从{}开始的reduce函数,然后我们希望在每次迭代中将当前元素的id和名称添加到哈希表中。这是我提出的,看起来非常错误。我接近了吗

var a = [{id: 1, name: 'one'}, {id: 2, name: 'two'},{id: 3, name: 'three'},{id: 4, name: 'four'} ]
var b = R.reduce(R.assoc(R.prop('id'), R.prop('name')), {}, a)
b

您可以通过以下方式实现这一点:

 var a = [{id: 1, name: 'one'}, {id: 2, name: 'two'},{id: 3, name: 'three'}]

 var b = R.reduce((dict, item) => ({ ...dict, [ item.id ] : item.name }), {}, a)
此方法使用es6语法,在每次还原迭代期间,将带有值(
item.name
)的键(通过
item.id
)添加到生成的词典中。

尝试使用以下代码:

   var a = [{id: 1, name: 'one'}, {id: 2, name: 'two'},{id: 3, name: 'three'}]
    R.map(i=> {
      var n = []
      n[R.keys(i)[0]] = i.name
      return n
    },a)

使用es6时,您可以获得更灵活的解决方案

a=[{id:1,name:'one'},{id:2,name:'two'},{id:3,name:'twree'}];
释放=a.reduce((acc,{id,name})=>{
acc[id]=名称;
返回acc;
}, {});

console.log(out)
您可以循环初始数组并分配给新对象:

var a=[{id:1,名称:'one'},{id:2,名称:'two'},{id:3,名称:'twree'}];
var new_a={};
a、 forEach(函数(e){
new_a[e.id]=e.name;
});
控制台日志(新的)您可以创建管道()将对象数组转换为哈希:

  • 获取每个()对象的属性()的值
  • 将成对数组转换为对象()
  • const a=[{id:1,name:'one'},{id:2,name:'two'},{id:3,name:'three'}];
    const convertToHash=(道具)=>
    右管(
    R.map(R.props(props)),
    R.fromPairs
    );
    const result=convertToHash(['id','name'])(a);
    控制台日志(结果)
    
    有很多方法可以解决这个问题。所有其他正确答案都有助于说明这一点。我会在下面列出我自己的一些。但首先,

    为什么你的方法不起作用 您尝试这样做:

    R.reduce(R.assoc(R.prop('id'), R.prop('name')), {}, a)
    
    很清楚你想在这里做什么。问题在于
    R.prop('id')
    R.prop('name')
    都是函数<代码>R.assoc
    不接受函数;它需要一个字符串(实际上是一个数字)和一个任意值。因此,
    assoc
    将不会以这种方式使用它们

    清理这个问题的一个尝试是认识到函数可以被看作是值的容器。在某种程度上——也许令人惊讶,但非常有用——函数是其返回值的容器。旨在将处理值的函数转换为处理值容器的函数。它的工作原理如下:
    R.multiply
    接受数字。如果我们提升
    乘法
    ,结果函数将接受数字容器。像这样:

    R.lift(R.multiply)(Maybe.Just(5), Maybe.Just(3))  // Maybe.Just(15)
    
    如果我们提供了两个函数
    lift(multiply)
    ,那么我们将返回一个函数,该函数返回其返回值相乘的结果:

    const area = R.lift(R.multiply)(prop('width'), prop('height'))
    area({width: 5, height: 3})
    
    因此,也许我们可以用
    升降机更新您的技术:

    R.reduce(R.lift(R.assoc)(R.prop('id'), R.prop('name'), identity), {}, a)
    
    不幸的是,这又失败了。这次的问题是
    reduce
    接受二进制回调,同时提供累加器和当前值。但是
    R.prop('id')
    R.prop('name')
    不承认这一点。他们寻找累加器上的相关属性,而这些属性根本不存在

    我们可能仍然能够解决这个问题,但在这一点上,我们将失去这个解决方案的许多简单性。让我们看看其他的可能性

    一些解决方案 简单还原 这两个版本中的每一个都使用一个简单的
    reduce
    调用,正如您的解决方案所尝试的那样:

    const convertToHash = reduce((acc, {id, name}) => merge(acc, {[id]: name}), {})
    

    他们几乎一样。两者都在每次迭代中创建一次性对象。在第一种方法中,您可以将
    R.merge
    替换为
    Object.assign
    ,而不存在任何实际问题,因为产生的变异是函数内部的。第二个看起来稍微优雅一些,但它在每次迭代中都会重建整个累加器。随着ES6引擎优化的进行,这可能最终不会成为性能问题,但现在可能是,特别是在性能关键代码中

    使用
    zipWith
    Ramda的
    zip
    函数采用两个列表,并将它们逐位置合并到一个列表中。接受用于将两个元素合并为一个元素的函数。这里我们使用,它将名称和值转换为单个属性对象。(
    objOf('foo',42)/=>{foo:42}
    ):

    如上所述,我们使用
    lift
    使这个
    zipWith(objOf)
    与函数一起工作。这会产生类似于
    [{“1”:“one”}、{“2”:“two”}、{“3”:“three”}]
    的结果,然后将其传递给创建单个对象

    使用
    props
    fromPairs
    此解决方案使用和
    fromPairs
    接受名称-值对列表(作为两个元素数组),并将它们转换为单个对象<代码>道具
    将命名属性拉入独立数组。在原始列表上,这为我们提供了从配对到
    的输入:

    const convertToHash = compose(fromPairs, map(props(['id', 'name'])))
    

    虽然我喜欢
    zipWith
    解决方案,并且如果它的输出是我想要的,我会使用它,但是必须添加
    mergeAll
    ,这使得它更难一眼理解。所以这个解决方案在我看来是最好的Ramda选择

    一般来说,如果答案中包含对代码意图的解释,以及在不介绍其他代码的情况下解决问题的原因,那么答案会更有帮助。这个答案需要
    减少
    !这确实帮助我理解了这个问题。非常感谢。
    
    const convertToHash = reduce((acc, {id, name}) => merge(acc, {[id]: name}), {})
    
    const convertToHash = reduce((acc, {id, name}) => ({...acc, [id]: name}), {})
    
    const convertToHash = compmose(mergeAll, lift(zipWith(objOf))(pluck('id'), pluck('name')))
    
    const convertToHash = compose(fromPairs, map(props(['id', 'name'])))