2017-10-20 1 views
0
Ramda

Je suis en train de transformer l'entrée suivante qui est un tableau de JSON à la sortie prévue ci-dessous. indexCols est égalementCoincé sur la composition

var objects = ['{"ticker":"MSFT", "key": 2, "PX_LAST":100}', 
       '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 
       '{"ticker":"GOOG", "key": 4, "PX_LAST":100}'] 

/* Expected output 
    [[id, '{"ticker":"MSFT", "key": 2, "PX_LAST":100}', 'MSFT', 2 ] 
    [id, '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 'AAPL', 3 ] 
    [id, '{"ticker":"GOOG", "key": 4, "PX_LAST":100}', 'GOOG', 4 ]] 
*/ 
var indexCols = ['ticker', 'key'] 

var transform = function(input, indexCols, id) { 
    var fn2 = R.compose(R.flip(R.map)(indexCols), R.flip(R.prop), JSON.parse) 
    var fn3 = R.map(R.compose(R.concat([id]), fn2)) 
    return fn3(objects) 
} 

transform(objects, indexCols, 100) 
/* result : [[100, "MSFT", 2], [100, "AAPL", 3], [100, "GOOG", 4]] */ 

Comme vous pouvez le voir les tableaux de résultats manquent le deuxième élément qui est la chaîne JSON. Je suis incapable de tisser cela d'une manière fonctionnelle.

Répondre

0

Ceux-ci semblent inutilement complexes ...

Que diriez-vous:

const objects = ['{"ticker":"MSFT", "key": 2, "PX_LAST":100}', 
       '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 
       '{"ticker":"GOOG", "key": 4, "PX_LAST":100}'] 
const indexCols = ['ticker', 'key', 'PX_LAST'] 

const pickIndeces = pipe(JSON.parse, props(indexCols)) 
const format = map(x => concat([x], pickIndeces(x))) 
format(objects) 

Note, pipe, props, concat et map sont des fonctions Ramda. Ainsi, vous pouvez les importer, comme ceci:

const { concat, map, pipe, props } = R 
+0

Merci de m'avoir indiqué les accessoires – Satish

1

(Je pense qu'il ya une faute de frappe, au lieu de ceci: Fn3 de retour (objets) vous signifie probablement ceci: FN3 (entrée de retour))

var transform = function(input, indexCols, id) { 
     var fn2 = R.compose(R.flip(R.map)(indexCols), R.flip(R.prop), JSON.parse); 
     var valueToArray = R.flip(R.append)([]); 
     var fn3 = R.map(R.compose(R.flatten, R.concat([id]), R.compose(R.ap([R.identity, fn2]), valueToArray))) 
     return fn3(input) 
    } 

https://codepen.io/anon/pen/Jrzmda

Vous devez dupliquer votre entrée objet (a -> [a, a]), alors vous pouvez utiliser sur le deuxième élément que vous le souhaitez (Fn2), juste garder le premier élément intact (identité), et, à la fin, concat tous ensemble.

Amélioration 1: Y at-il une fonction pour valueToArray Ramda (a -> [a]) déjà? amélioration 2: Est-il possible de concaténer id pas imbriqué pour se débarrasser de la R.flatten?

1

Vous pouvez utiliser R.converge afin que vous puissiez nourrir la chaîne à concaténer et JSON.parse:

var objects = ['{"ticker":"MSFT", "key": 2, "PX_LAST":100}', 
 
       '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 
 
       '{"ticker":"GOOG", "key": 4, "PX_LAST":100}'] 
 

 
/* Expected output 
 
    [[id, '{"ticker":"MSFT", "key": 2, "PX_LAST":100}', 'MSFT', 2 ] 
 
    [id, '{"ticker":"AAPL", "key": 3, "PX_LAST":100}', 'AAPL', 3 ] 
 
    [id, '{"ticker":"GOOG", "key": 4, "PX_LAST":100}', 'GOOG', 4 ]] 
 
*/ 
 
var indexCols = ['ticker', 'key'] 
 

 
var transform = function(input, indexCols, id) { 
 
    //Have to trick R.converge into making it think that JSON.parse only has 1 argument 
 
    var fn2 = R.compose(R.flip(R.map)(indexCols), R.flip(R.prop), R.curryN(1, JSON.parse)) 
 
    var fn3 = R.map(R.compose(R.concat([id]), R.converge(R.concat, [Array, fn2]))) 
 
    return fn3(input) //typo shouldn't be objects 
 
} 
 

 
console.log(transform(objects, indexCols, 100)) 
 
/* result : [[100, "MSFT", 2], [100, "AAPL", 3], [100, "GOOG", 4]] */
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

Une alternative pourrait consister à utiliser:

R.ap(R.compose(R.concat, Array), fn2)) 
// concat <$> Array <*> fn2 
// R.liftN(2, R.concat)(Array, fn2) is the same 

Au lieu de :

R.converge(R.concat, [Array, fn2]) 

De cette façon, vous ne courez pas dans R.converge problème où il est deviner JSON.parse a 2 arguments.

+0

@Satish, le aplicative des fonctions est 'f => g => x => f (x) (g (x))' et la carte des fonctions est composez 'f => g => f (g (x))' si vous utilisez la fonction composée comme premier paramètre pour l'aplicatif, vous obtiendrez 'f => g => h => x => f (g (x)) (h (x)) 'qui est fondamentalement' liftA2' pour les fonctions. – MinusFour