Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何用Ramda模拟lodash.set_Javascript_Ramda.js - Fatal编程技术网

Javascript 如何用Ramda模拟lodash.set

Javascript 如何用Ramda模拟lodash.set,javascript,ramda.js,Javascript,Ramda.js,我正在学习拉姆达,我很困惑。我想制作一个集合函数,其工作原理与lodash.set函数类似。但是,当我在对象中存在的路径上尝试以下操作时,它似乎按预期工作,但是当我使用它创建新路径时,它添加了这个奇怪的数组 const R = require('ramda') const set = (object, path, value) => R.set(R.lensPath(path), value, object); const foo = { moo: { goo: 'goo'

我正在学习拉姆达,我很困惑。我想制作一个集合函数,其工作原理与lodash.set函数类似。但是,当我在对象中存在的路径上尝试以下操作时,它似乎按预期工作,但是当我使用它创建新路径时,它添加了这个奇怪的数组

const R = require('ramda')

const set = (object, path, value) => R.set(R.lensPath(path), value, object);

const foo = {
  moo: {
    goo: 'goo'
  }
}


set(foo, ['moo', 'goo', 'boo'], 'roo'); // { moo: { goo: { '0': 'g', '1': 'o', '2': 'o', boo: 'roo' } } }
所以结果是://{moo:{goo:{0':'g',1':'o','2':'o',boo:'roo'}}

当我期望它是://{moo:{goo:{boo:'roo'}}

为什么要按索引添加这些字符?如何使用Ramda实现lodash.set函数


这似乎是不想要的行为。为什么会有人想让拉姆达强迫绳子

我认为这是一个不同的问题。当
foo.moo.goo
是一个字符串时,您正在编写的代码应该执行与
foo.moo.goo.boo='roo'
模糊等效的操作。这当然会引发一个错误,例如
无法在字符串“goo”上创建属性“boo”

洛达斯回答说:“哦,你一定是指
foo.moo.goo={boo:roo'}
”这是一个完全合理的猜测。但这只是猜测。库是否应该抛出如上所述的错误?这可能是最合乎逻辑的做法

Ramda(免责声明:我是它的作者之一)做出了不同的选择。它假设你说的是真的。您想要更新
foo.moo
goo
属性,方法是将其
boo
属性设置为
'roo'
。然后它就这样做了。但是,当它像其他地方一样更新这样的属性时,它不会改变原始数据,而是为您构建一个新的输出,复制旧对象的属性,但新路径除外,它会相应地设置。好的,您的旧对象(
'goo'
)有三个属性,
{0:g'}
{1:o'}
,以及
{2:o'}
,Ramda的
assocPath
(执行此任务的
lensPath
也使用公共函数)然后与
{boo:roo'}
合并成一个对象

但我在这里夸大了。拉姆达从未真正做出过这样的选择。这仅仅是实施过程中出现的问题
assocPath
只知道两种类型:数组和对象。它只知道如何重构这些类型。实际上,它可以作为数组和其他数组使用。由于您的
foo.moo
不是数组,因此它将其视为对象

如果你想看到这种行为改变,a,甚至更好的a会得到公平的听证。我可以向你保证

但我预计会有很多阻力

拉姆达的哲学与洛达斯的哲学截然不同。洛达斯强调灵活性<例如,code>set允许您以数组或字符串的形式编写路径,其中有两个示例

\uu0.set(对象'a[0].b.c',4);
_.set(对象,['x','0','y','z'],5);
许多函数都有可选参数。它可以自由地修改提供给它的数据。它的设计宗旨是“为尽可能多的开发人员提供高质量的实用方法,重点关注一致性、兼容性、定制和性能。”

相比之下,拉姆达对灵活性的担忧要小得多。Ramda更重要的目标是简单性。它的API没有可选参数。当一个参数允许多种类型时,这只是因为它们共享一个更高的抽象。提供给
assocPath
的路径是一个数组,并且仅是一个数组;它通过注意每个path元素是字符串还是整数来处理对象与数组。当然,拉姆达从不改变你的输入数据

拉姆达对牵手也不感兴趣。哲学通常是垃圾进,垃圾出。这个案子似乎已经进入了这一领域。拉姆达愿意把
{moo:{goo:'goo'}}
转换成
{moo:{goo:{boo:'roo'}}}
。但是你必须更明确地告诉它:
assoc(['moo','goo'],{boo:'roo'})

因此,要求改变这一点可能是一个困难的销售。。。但这是一个友好的人群。如果你认为它很重要的话,请随时提出来

我觉得我只需要从lodash导入
set
函数,以防止意外行为

不过,请记住,这些行为是多么的不同。最大的区别是lodash正在改变它的输入,而Ramda不会这样做。他们对哪些值需要增强,哪些值需要替换有不同的想法(如当前示例中所示)。当然,他们的签名是不同的。它们在数组索引方面有不同的行为。(例如,我想不出在lodash的
集合中添加一个字符串键为“0”的对象的方法。当你调用
assocPath(['grid','width',newVal,myObj)
之类的东西时,Ramda当然不会包含一个构造好的矩形,而lodash会很高兴地对内部矩形对象进行变异。)


换句话说,它们是不同的行为,为不同的目的而设计。如果lodash的行为是你想要的,那么一定要包括在内。但是,如果您在大多数实用程序工作中使用Ramda,请注意它们的原理有多么不同。

您要求它在字符串上设置一个新属性,但实际上没有一个理想的解决方案是js。Ramda通过首先将字符串强制到具有索引属性的对象,然后添加新属性来尝试不丢失信息。Ramda已经有一个类似于函数-R.assocPath的集合,但是字符串也会有同样的强制问题。这似乎是不需要的行为。为什么会有人想让拉姆达强迫绳子?这种行为有什么好处?我觉得我必须从lodash中导入set函数以防止意外行为。