2016-09-02 7 views
1

Ich habe die folgende Eingabe:eine zweidimensionale spärliche Ergebnismenge mit Ramdajs

var data = [{ 
     month: '2016-01', 
     city: 'Paris', 
     count: 6 
    }, { 
     month: '2016-01', 
     city: 'London', 
     count: 2 
    }, { 
     month: '2016-02', 
     city: 'Paris', 
     count: 15 
    }, { 
     month: '2016-03', 
     city: 'London', 
     count: 17 
    }]; 
var cityList = ['Paris', 'London']; 

Die Daten spärlich ist, weil es ohne alle Städte Monate und Städte ohne alle Monate.

Ich möchte diesen Hash in folgendem Format zu transformieren:

rowsByCity = [{ 
    city: 'Paris', 
    counts: [6, 15, null] 
}, { 
    city: 'London', 
    counts: [2, null, 17] 
}]; 

Wie kann ich das mit Ramdajs (docs)? (Ich habe nichts gegen eine reine js-Lösung, wenn es einfach ist)

Idealerweise möchte ich vermeiden, leere Monate mit [null, null, null] vorzufüllen und hinein zu mischen. Vielleicht durch direkte Verwendung einer Transformation auf die Daten (Transponieren?). Aber ich bin mir nicht sicher, wie es geht oder ob es möglich ist.

Fiddle hier: https://jsfiddle.net/dtr0js55/

Antwort

0

bekam ich eine Lösung, aber es geht in eine vorge besiedelten Monate Liste verschmelzen.

Ich bin sicher, dass dies einfacher gemacht werden kann

var months = R.uniq(R.pluck('month', data)); 
var defaultMonths = R.zipObj(months, R.repeat(null, months.length)); 
var result = R.mapObjIndexed(
    function(counts, city) { 
    return { 
     city: city, 
     counts: R.values(R.merge(
     defaultMonths, 
     R.mapObjIndexed(R.prop('count'), R.indexBy(R.prop('month'), counts)) 
    )) 
    }; 
    }, 
    R.groupBy(R.prop('city'), data)) 

Fiddle hier: https://jsfiddle.net/s141r74y/

1

Es ist sicherlich nicht schön, und es ist auch nicht sehr effizient, aber hier ist etwas, das ich denke, funktioniert:

const extract = R.converge(
    (data, cities, months) => R.map(city => ({ 
    city, 
    counts: R.map(month => (
     R.find(record => record.city === city && 
         record.month === month, data) || 
     {count: null} 
    ).count, months) 
    }), cities), [ 
    R.identity, 
    R.compose(uniq, pluck('city')), 
    R.compose(uniq, pluck('month')) 
]); 

extract(data); 
+0

Ich denke, das ist etwas kühler als meine Version. Auch ich wusste nichts über konvergieren. +1 –

+0

Converge ist nützlich, wenn Sie wirklich etwas punktefrei machen wollen. Ramda hat auch eine etwas verwandte Funktion, ['useWith'] (http://ramdajs.com/docs/#useWith), die gelegentlich hilfreich sein kann. –

0

Eine andere Lösung mit xprod:

var months = R.uniq(R.pluck('month', data)); 
var cities = R.uniq(R.pluck('city', data)); 
var result = R.values(R.mapObjIndexed(
    (array, city) => { 
    return { 
     city: city, 
     counts: array.map((attrs) => { 
     return R.find((record) => { 
      return record.city === attrs[0] && record.month === attrs[1]; 
     }, data) 
     }).map(R.path(['count'])) 
    } 
    }, 
    R.groupBy(R.prop(0), R.xprod(cities, months)))); 

console.log(result) 

Geige hier: https://jsfiddle.net/44ysat8d/

Verwandte Themen