2017-11-14 3 views
0

Wie kann ich ramdas sequence verwenden, um ein Wörterbuch zu durchlaufen?Verwenden Sie ramda `sequenz`, um ein Wörterbuch zu durchlaufen

folgende Wörterbuch

cars = {color: ['yellow', 'red'], year: [2017], model: ['coup', 'sedan']} 

Gegeben Ich mag würde das Ergebnis durchlaufen

all_cars = [ 
    {color: 'yellow', year: 2017, model: 'coup'}, 
    {color: 'yellow', year: 2017, model: 'sedan'}, 
    {color: 'red', year: 2017, model: 'coup'}, 
    {color: 'red', year: 2017, model: 'sedan'} 
] 

Mit R.sequence Ergebnisse in einer Liste von einer leeren Liste

R.sequence(R.of, cars) 
[[]] 

Wenn ich produzieren Durchqueren Sie eine Liste anstelle eines Wörterbuchs, es erzeugt das korrekte kartesische Produkt, aber die res ults sind (natürlich) Listen statt Wörterbücher.

R.sequence(R.of, [['yellow', 'red'], [2017], ['coup', 'sedan']]) 
[["yellow", 2017, "coup"], ["yellow", 2017, "sedan"], ["red", 2017, "coup"], ["red", 2017, "sedan"]] 

Antwort

1

kann ich mich zwei Möglichkeiten, dies zu tun, eine Beteiligung sequence, und der andere nicht.

Dieses verwendet Ihre sequence(of) Aufruf über:

const convert = lift(map)(
    compose(zipObj, keys), 
    compose(sequence(of), values) 
) 

const all_cars = convert(cars); 

Die andere durch meine übliche Technik des Bergfrieds gebaut wurde die Ausgabe mit einer Transformation nach dem anderen zu ändern, bis ich zu dem, was bekomme ich will:

const combine = pipe(
    toPairs, 
    map(apply(useWith(map, [objOf, identity]))), 
    reduce(xprod, [[]]), 
    map(flatten), 
    map(mergeAll) 
) 

const all_cars = combine(cars) 

Dies könnte durch die Einführung eines Kreuzprodukts über mehrere Listen ein wenig klarer gemacht werden:

const xproduct = reduce(pipe(xprod, map(unnest)), [[]]) 

const combine = pipe(
    toPairs, 
    map(apply(useWith(map, [objOf, identity]))), 
    xproduct, 
    map(mergeAll) 
) 

Die zweite Version ist, was ich beim ersten Versuch das Problem kam. Dann, als ich nachgesehen habe, was du versucht hast, habe ich diese erste Version bekommen. Diese erste Version sieht für mich sauberer aus, obwohl die meisten einzelnen Schritte in der zweiten Version trivial sind. Aber da es dort einen nicht-trivialen Schritt gibt, scheint der erste ein Gesamtsieger zu sein.

Sie können the first oder the second auf der Ramda REPL sehen.

+0

Das funktioniert, aber sicherlich sollte es eine Fantasy-Land 'Traversable' Instanz für Wörterbücher zu nutzen. – Cirdec

+0

Ramda hat [debattiert] (https://github.com/ramda/ramda/issues/2046) zahlreiche Male. Es ist schwer, überhaupt etwas gegen ein Objekt faltbar zu machen, wenn man eine nicht-kommutative Funktion haben könnte, und man möchte immer noch '{a: 1, b: 2}' und '{b: 2, a: 1}' zu sein gleich. –

+0

Verrückt. Die Berücksichtigung von '{a: 1, b: 2} = {b: 2, a: 1}' schließt nicht die Auswahl einer kanonischen Reihenfolge für 'Traversable' aus. – Cirdec

Verwandte Themen