2016-09-25 1 views
4

J'ai actuellement une structure de données qui ressemble la plupart du temps comme suit:Modification de plusieurs objets à l'aide de lentilles Ramda

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": {}} 
      ] 
     }] 
    }] 
} 

J'ai essayé d'utiliser Ramda pour faire une requête de composition qui pourrait faire quelque chose comme, changer le statut de toutes les questions qui sont d'un certain type.

J'ai essayé de faire quelque chose dans le cadre de la composition de l'objectif à travers R.map/R.chain mais je n'arrive pas à le résoudre. Quelque chose comme ceci est ce que im essayant de faire:

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) 

et avoir revenir en arrière les données complet avec les statuts modifiés.

MISE À JOUR:

Je suis venu avec un code qui va faire ce que je suis en train de faire, mais je suis encore du mal à faire chacune des étapes dans des fonctions qui peuvent ensuite être composés:

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) 

Répondre

4

Votre solution mise à jour semble bien pour moi, mais il est possible de créer la fonction de transformation par 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); 
+0

Pourquoi $ (dollar) sur la mise à jour des modules de $ résultats $ problèmes de $ statut de $? Est-ce quelque chose lié à la PF? Je vous remercie. –

+0

Aucune raison particulière. Underscores serait également bon. – davidchambers

3

Il semble que vous ayez des doutes sur la transformation des valeurs dans les tableaux.

Maintenant, les données étant

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": {}} 
     ] 
    }] 
    }] 
}; 

Ce que vous voulez faire est de créer des lentilles pour chacune des touches qui contiennent des tableaux. Dans votre cas spécifique, ils sont modules, results et issues.

En plus de cela, vous aurez besoin d'un objectif à la clé que vous voulez modifier, qui est status.

Alors:

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

Maintenant, avec ces éléments en place, tout ce que vous avez à faire est de les mettre ensemble. (Je les ai cassé vers le bas pour faciliter la compréhension)

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

Maintenant, tout ce qui reste à faire est de nourrir approvedIssues avec les données que vous souhaitez transformer, ce qui est notre data.

Alors, enfin.

//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" 
    }]} 
    ]} 
*/ 

Dans ce cas, je n'ai pas nécessairement à utiliser compose, mais ce serait aussi possible que je suppose.