无论如何在 Ramda 中使用路径和占位符?

Ric*_*ard 0 javascript ramda.js

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

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

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

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

path(['a', 'b', __, 'd', 'e'])
Run Code Online (Sandbox Code Playgroud)

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

Ric*_*ter 5

回答“问题的召唤”(有启发性):

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

fn('c') //=> 1
Run Code Online (Sandbox Code Playgroud)

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

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

Run Code Online (Sandbox Code Playgroud)

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

注意:在 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)
Run Code Online (Sandbox Code Playgroud)

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

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

// from question
['a', 'b', property, 'd', 'e']
Run Code Online (Sandbox Code Playgroud)

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

R.insert(2, R.__, ['a', 'b', 'd', 'e'])
Run Code Online (Sandbox Code Playgroud)

您的问题意味着在您知道丢失的路径键(“问题的调用”)之前,您将知道将要查询的对象。

// from question
{ a: { b: { c: { d: { e: 1 } } } } }
Run Code Online (Sandbox Code Playgroud)

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

R.path(R.__, { a: { b: { c: { d: { e: 1 } } } } })
Run Code Online (Sandbox Code Playgroud)

所以,把它们放在一起:

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

这种循序渐进的数据流是基本的函数组成,可以用 简洁地表示R.pipe。

同样,奇怪的是您会知道数据和除一个之外的所有路径键。然而,上述方法和思维过程可以被转移到这将可能是你的真实世界的情况不依赖R.insert,但会要求你建立一个脚印的路径步骤,然后让所述路径R.path。