简体   繁体   English

使用Ramda镜头更换多个物体

[英]Changing multiple objects using Ramda lens

I currently have a data structure that looks mostly like that following: 我目前的数据结构看起来大致如下:

var data = { "id": 123,
    "modules": [{
        "id": 1,
        "results": [{
            "status": "fail",
            "issues": [
                {"type": "change", "status": "warn", "data": {}},
                {"type": "remove", "status": "warn", "data": {}},
                {"type": "change", "status": "warn", "data": {}}
            ]
        }]
    },{
        "id": 2
        "results": [{
            "status": "pass",
            "issues": [
                {"type": "change", "status": "warn", "data": {}},
                {"type": "remove", "status": "warn", "data": {}},
                {"type": "change", "status": "warn", "data": {}}
            ]
        }]
    }]
}

I have been trying to use Ramda to make a compose query that could do something like, change the status of all issues that are of a certain type. 我一直在尝试使用Ramda来创建一个可以执行类似操作的撰写查询,更改某些类型的所有问题的状态。

I have been trying to do something along the lines of composing the lens's through R.map/R.chain but I can't seem to work it out. 我一直试图通过R.map/R.chain来构建镜头,但我似乎无法解决这个问题。 Something like this is what im trying to do: 这样的事情是我想要做的:

let approvedData = R.compose(
  R.set(R.__, 'approve', Data)
  R.lensProp('status')
  R.map(R.lensIndex),
  R.lensProp('issues'),
  R.map(R.lensIndex),
  R.lensProp('results'),
  R.map(R.lensIndex),
  R.lensProp('modules')
)(Data)

And have it return back the full data set with the statuses changed. 并让它返回完整数据集并更改状态。

UPDATE: 更新:

I have come up with some code that will do what I'm trying to do, but I'm still struggling to make each of the steps into functions that can then be composed: 我已经提出了一些代码来完成我正在尝试做的事情,但是我仍然在努力将每个步骤转换为可以编写的函数:

R.over(R.lensProp('modules'), R.map(
  R.over(R.lensProp('results'), R.map(
    R.over(R.lensProp('issues'), R.map(
      R.set(R.lensProp('status'), 'approve')
    ))
  ))
), Data)

Your updated solution looks fine to me, but it is possible to create the transformation function via composition: 您更新的解决方案对我来说很好,但可以通过组合创建转换功能:

//  update$modules$results$issues$status :: (String -> String) -> Object -> Object
var update$modules$results$issues$status = R.compose(
  R.over(R.lensProp('modules')),
  R.map,
  R.over(R.lensProp('results')),
  R.map,
  R.over(R.lensProp('issues')),
  R.map,
  R.over(R.lensProp('status'))
);

update$modules$results$issues$status(R.always('approve'))(data);

It seems you're probably having doubts around the transformation of values within arrays. 看起来你可能对数组中值的转换感到怀疑。

Now, with the data being 现在,随着数据的存在

const data = {
  "id": 123,
  "modules": [{
    "id": 1,
    "results": [{
      "status": "fail",
      "issues": [
        {"type": "change", "status": "warn", "data": {}},
        {"type": "remove", "status": "warn", "data": {}},
        {"type": "change", "status": "warn", "data": {}}
      ]
    }]
  },{
    "id": 2,
    "results": [{
      "status": "pass",
      "issues": [
        {"type": "change", "status": "warn", "data": {}},
        {"type": "remove", "status": "warn", "data": {}},
        {"type": "change", "status": "warn", "data": {}}
      ]
    }]
  }]
};

What you want to do is create lenses for each of the keys that contain arrays. 你想要做的是为每个包含数组的键创建镜头。 In your specific case they are modules , results and issues . 在您的具体情况下,它们是modulesresultsissues

On top of that, you'll need a lens to the key you want to modify, which is status . 最重要的是,你需要一个镜头来修改你想要修改的键,这就是status

So: 所以:

const modulesLens = lensProp('modules')
const resultsLens = lensProp('results')
const issuesLens = lensProp('issues')
const statusLens = lensProp('status')

Now, with these in place, all you have to do is put them together. 现在,有了这些,你所要做的就是将它们组合在一起。 (I've broken them down to facilitate the comprehension) (我把它们分解以便于理解)

const approveIssues = over(
  modulesLens,
  map(over(
    resultsLens,
    map(over(
      issuesLens,
      map(set(statusLens, 'approve'))
    ))
  ))
)

Now all that's left to do is feed approvedIssues with the data you'd like to transform, which is our data . 现在剩下要做的就是使用您想要转换的数据来提供approvedIssues的问题,这是我们的data

So, finally. 所以,最后。

//Running this
const approvedData = approveIssues(data)

/* Outputs this
{
  "id": 123,
  "modules": [{
    "id": 1,
    "results": [{
      "issues": [
        {"data": {}, "status": "approve", "type": "change"},
        {"data": {}, "status": "approve", "type": "remove"},
        {"data": {}, "status": "approve", "type": "change"}
      ],
      "status": "fail"
    }]}, {
      "id": 2,
      "results": [{
        "issues": [
          {"data": {}, "status": "approve", "type": "change"},
          {"data": {}, "status": "approve", "type": "remove"},
          {"data": {}, "status": "approve", "type": "change"}],
        "status": "pass"
    }]}
  ]}
*/

In that case I didn't necessarily have to use compose , but that would be possible as well I guess. 在那种情况下,我不一定要使用compose ,但我认为这也是可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM