首页 > 解决方案 > 无论如何在 Ramda 中使用路径和占位符?

问题描述

我在 Ramda 中尝试了一些东西,我坚持尝试使用纯粹的 Ramda 在对象内部深入获取属性值。

我只能包装一个函数来接收路径的缺失部分:

const fn = property => path(['a', 'b', property, 'd', 'e']);
fn('c')({ a: { b: { c: { d: { e: 1 } } } } });

我也尝试使用R.__,但它根本不起作用:

path(['a', 'b', __, 'd', 'e'])

1如果通过结果函数缺少道具,我如何使用纯粹的 Ramda 进入该对象?

标签: javascriptramda.js

解决方案


回答“问题的呼唤”(指导性):

const fn = R.pipe(
  R.insert(2, R.__, ['a', 'b', 'd', 'e']),
  R.path(R.__, { a: { b: { c: { d: { e: 1 } } } } })
)

fn('c') //=> 1

回答“实际问题”(假设数据流不合理):

const fn = R.compose(
  R.path,    // see NOTE
  R.insert(2, R.__, ['a', 'b', 'd', 'e'])
)

fn ('c') ({ a: { b: { c: { d: { e: 1 } } } } }) //=> 1

您的问题意味着您将知道将要查询的对象,然后才能知道缺少的路径键(“问题调用”)。如果您在知道数据之前就知道路径键,那么只需使用以下方法来求解数据而不是路径。如果您会同时知道丢失的键和数据,那么您可以只调用该函数,或者根据情况可能想要使用超出问题范围的组合器。

注意:在 Ramda 中,pipe将与composereversed 一样工作,因此您可以pipe改用并切换参数;但是,其他库有更严格的定义,compose并且pipe会将pipe' 的参数限制为一元函数,因此compose尽管在这种情况下是等价的,但还是首选。

解释:

你走在正确的道路上,你只需要稍微调整几个概念。

首先,R.__是为了代替一个未知的论点(整个论点)。在这里,您错误地尝试R.__在参数中使用。考虑以下:

const add = (x, y) => x + y
const curriedAdd = R.curry(add)

// the following are equivalent
const add2 = placeholder => add(placeholder, 2)
const add2 = curriedAdd(R.__, 2)

希望从上面可以清楚地看出,这R.__只是一种说法:“嘿,Javascript,我还不知道这个参数的值,请保存我知道的参数并等待运行这个函数,直到我知道其余的论点。” 它是您在问题中提出的解决方案的语法糖(顺便说一句,这是解决问题的完全可以接受的方法)。

其次,你只需要再分解一下你的问题。从你知道的信息开始,朝着你不知道的方向努力。您的问题假定您知道路径中的所有元素,除了一个;但是,您也知道缺失属性的索引,即2

// from question
['a', 'b', property, 'd', 'e']

奇怪的是你会知道路径的所有其他元素和未知键的索引,但是,嘿,这是假设的,我假设。在这种情况下,R.insertR.__可以用来表示已知和未知的信息:

R.insert(2, R.__, ['a', 'b', 'd', 'e'])

您的问题意味着您将知道将要查询的对象,然后才能知道缺少的路径键(“问题调用”)。

// from question
{ a: { b: { c: { d: { e: 1 } } } } }

如果您不知道路径的所有元素,那么在R.insert被调用之前您将不会知道完整的路径。相反,一旦R.insert被调用,您就会知道完整路径。首先,考虑一下R.path您还不知道路径的地方会是什么样子:

R.path(R.__, { a: { b: { c: { d: { e: 1 } } } } })

所以,把它们放在一起:

  1. fn在使用缺少的键调用 之前,我们不会知道完整路径。
  2. 一旦我们知道路径,我们就可以调用R.path来检索值。

这种逐步的数据流是基本的函数组合,可以用R.pipe.

同样,奇怪的是您会知道数据和除一个之外的所有路径键。但是,上述方法和思维过程可以转移到您的实际情况中,这可能依赖于您,R.insert而是需要您逐步构建路径,然后将所述路径传递给R.path.


推荐阅读