合并对象字段以使用 Ramda 创建新字段
Merge fields of object to create new field with Ramda
我有一个集合,我想从中获取一些值,并将它们合并在一起形成一个新值。到目前为止,我已经看过 R.evolve
,但没有运气(因为 medias
也是一个集合。
这就是我的开头:
[{
"permalink": "http://example.com/1",
"medias": [{
"filename": "image_1.png",
}]
}, {
"permalink": "http://example.com/3",
"medias": [{
"filename": "image_3.png",
}]
}]
这就是我想结束的:
[{
"permalink": "http://example.com/1",
"medias": [{
"filename": "image_1.png",
"image_url": "http://example.com/1/image_1.png"
}]
}, {
"permalink": "http://example.com/3",
"medias": [{
"filename": "image_3.png",
"image_url": "http://example.com/3/image_3.png"
}]
}]
本质上,我们正在做的是在每个 filename
前面加上一个 permalink
。
这是我迄今为止一直在做的事情,不幸的是,当 运行 在 medias
上进行转换时,我无法访问 permalink
属性.
const mapMedia = R.map(
// can’t get access to the `permalink` in here?
)
const transformations = {
medias: mapMedia
}
const transform = R.compose(
R.map(R.evolve(transformations)),
)(data)
所以问题是您需要的数据不在范围内。在我看来,解决这个问题的最简单方法是添加一些范围!
首先,您不需要 compose
调用,因为您只提供了一个功能。所以我们可以替换
const transform = R.compose(
R.map(R.evolve(transformations)),
)(data)
只有
const transform = R.map(R.evolve(transformations)),
(我还删除了使用 (data)
的调用,因为我试图将其构建为可重用函数。稍后我们将使用 transform(data)
调用它。
现在我们必须添加上下文,以便 transformations
将对象包含在范围内。我们可以这样做:
const transform = R.map(image => R.evolve(transformations(image), image));
当然,这意味着 transformations
需要更改以考虑到这一点。我们可以这样做:
const transformations = image => ({
medias: mapMedia(image.permalink)
})
... 而这又需要更改为 mapMedia
。我认为它应该只需要知道永久链接而不是整个图像,所以我们可以像上面那样只传递它。 mapMedia
现在看起来像这样:
const mapMedia = permalink => R.map(
medium => // do something with `medium` and `permalink`
);
您可以通过多种方式完成这最后一步。其中之一,与您对 evolve
的使用相当一致:
const mapMedia = permalink => R.map(
medium => assoc('image_url', permalink + '/' + medium.filename, medium)
);
evolve
和 assoc
is to investigate the various lens
-related functions in Ramda, such as lensProp
, over
, and set
的另一种选择。
现在,如果这些辅助函数仅用于此目的,您可能不希望它们把事情弄得一团糟,您可以选择将它们内联到您的主函数中。如果你喜欢,你可以将以上所有内容组合成
const addUrls = map(
image => evolve({
medias: map(medium => assoc('image_url', image.permalink + '/' + medium.filename, medium)),
}, image)
);
可以看到separate functions approach or the combined one in the Ramda REPL. For good measure, there's also a version using lenses.
(另外,单词 "media" 已经是复数。单数是 "medium"。"medias" 没有充分的理由。)
我有一个集合,我想从中获取一些值,并将它们合并在一起形成一个新值。到目前为止,我已经看过 R.evolve
,但没有运气(因为 medias
也是一个集合。
这就是我的开头:
[{
"permalink": "http://example.com/1",
"medias": [{
"filename": "image_1.png",
}]
}, {
"permalink": "http://example.com/3",
"medias": [{
"filename": "image_3.png",
}]
}]
这就是我想结束的:
[{
"permalink": "http://example.com/1",
"medias": [{
"filename": "image_1.png",
"image_url": "http://example.com/1/image_1.png"
}]
}, {
"permalink": "http://example.com/3",
"medias": [{
"filename": "image_3.png",
"image_url": "http://example.com/3/image_3.png"
}]
}]
本质上,我们正在做的是在每个 filename
前面加上一个 permalink
。
这是我迄今为止一直在做的事情,不幸的是,当 运行 在 medias
上进行转换时,我无法访问 permalink
属性.
const mapMedia = R.map(
// can’t get access to the `permalink` in here?
)
const transformations = {
medias: mapMedia
}
const transform = R.compose(
R.map(R.evolve(transformations)),
)(data)
所以问题是您需要的数据不在范围内。在我看来,解决这个问题的最简单方法是添加一些范围!
首先,您不需要 compose
调用,因为您只提供了一个功能。所以我们可以替换
const transform = R.compose(
R.map(R.evolve(transformations)),
)(data)
只有
const transform = R.map(R.evolve(transformations)),
(我还删除了使用 (data)
的调用,因为我试图将其构建为可重用函数。稍后我们将使用 transform(data)
调用它。
现在我们必须添加上下文,以便 transformations
将对象包含在范围内。我们可以这样做:
const transform = R.map(image => R.evolve(transformations(image), image));
当然,这意味着 transformations
需要更改以考虑到这一点。我们可以这样做:
const transformations = image => ({
medias: mapMedia(image.permalink)
})
... 而这又需要更改为 mapMedia
。我认为它应该只需要知道永久链接而不是整个图像,所以我们可以像上面那样只传递它。 mapMedia
现在看起来像这样:
const mapMedia = permalink => R.map(
medium => // do something with `medium` and `permalink`
);
您可以通过多种方式完成这最后一步。其中之一,与您对 evolve
的使用相当一致:
const mapMedia = permalink => R.map(
medium => assoc('image_url', permalink + '/' + medium.filename, medium)
);
evolve
和 assoc
is to investigate the various lens
-related functions in Ramda, such as lensProp
, over
, and set
的另一种选择。
现在,如果这些辅助函数仅用于此目的,您可能不希望它们把事情弄得一团糟,您可以选择将它们内联到您的主函数中。如果你喜欢,你可以将以上所有内容组合成
const addUrls = map(
image => evolve({
medias: map(medium => assoc('image_url', image.permalink + '/' + medium.filename, medium)),
}, image)
);
可以看到separate functions approach or the combined one in the Ramda REPL. For good measure, there's also a version using lenses.
(另外,单词 "media" 已经是复数。单数是 "medium"。"medias" 没有充分的理由。)