Javascript 合并对象的字段以使用Ramda创建新字段

Javascript 合并对象的字段以使用Ramda创建新字段,javascript,ramda.js,Javascript,Ramda.js,我有一个集合,我想从中获取一些值,并将它们合并在一起形成一个新值。到目前为止,我已经看过了R.evolve,但运气不好(因为媒体也是一个集合) 这是我的开始: [{ "permalink": "http://example.com/1", "medias": [{ "filename": "image_1.png", }] }, { "permalink": "http://example.com/3", "medias": [{ "filename": "i

我有一个集合,我想从中获取一些值,并将它们合并在一起形成一个新值。到目前为止,我已经看过了
R.evolve
,但运气不好(因为
媒体
也是一个集合)

这是我的开始:

[{
  "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"
  }]
}]
基本上,我们所做的是在每个
文件名
前面加上
永久链接

这是我到目前为止一直在做的事情,不幸的是,在
媒体上运行转换时,我无法访问
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)
调用它

现在我们必须添加上下文,以便
转换
在作用域中包含对象。我们可以这样做:

const transform = R.map(image => R.evolve(transformations(image), image));
const transformations = image => ({
  medias: mapMedia(image.permalink)
})
const mapMedia = permalink => R.map(
  medium => // do something with `medium` and `permalink`
);
当然,这意味着
转换
需要更改才能考虑到这一点。我们可以这样做:

const transform = R.map(image => R.evolve(transformations(image), image));
const transformations = image => ({
  medias: mapMedia(image.permalink)
})
const mapMedia = permalink => R.map(
  medium => // do something with `medium` and `permalink`
);
…这反过来需要更改为
mapMedia
。我认为它应该只需要知道永久链接,而不需要知道整个图像,因此我们只能如上所述传递。而
mapMedia
现在看起来是这样的:

const transform = R.map(image => R.evolve(transformations(image), image));
const transformations = image => ({
  medias: mapMedia(image.permalink)
})
const mapMedia = permalink => R.map(
  medium => // do something with `medium` and `permalink`
);
您可以通过多种方法完成最后一步。其中一种方法与您的使用方法相当一致,即:

const mapMedia = permalink => R.map(
  medium => assoc('image_url', permalink + '/' + medium.filename, medium)
);
另一种方法是研究Ramda中与镜头相关的各种功能,例如,和

现在,如果这些助手函数仅用于此目的,您可能不希望它们把事情弄得一团糟,您可以选择将它们内联到主函数中

const addUrls = map(
  image => evolve({
    medias: map(medium => assoc('image_url', image.permalink + '/' + medium.filename, medium)),
  }, image)
);
您可以在Ramda REPL中看到方法或



(另一方面,“媒体”一词已经是复数了。单数是“媒体”。没有充分的理由使用“媒体”。)

你能告诉我们你到目前为止尝试了什么吗?@ScottSauyet当然!我刚刚加入了我到目前为止的尝试。非常感谢你给出了这个全面而出色的答案。这是我如此喜欢使用Ramda的原因之一!这是一个令人惊讶的回答。