2014-05-12 9 views
47

Ho questi dati di esempio restituiti da un'API.usando lodash .groupBy. come aggiungere le proprie chiavi per l'output raggruppato?

Sto usando il _.groupBy di Lodash per convertire i dati in un oggetto che posso usare meglio. I dati grezzi restituiti è questa:

[ 
    { 
     "name": "jim", 
     "color": "blue", 
     "age": "22" 
    }, 
    { 
     "name": "Sam", 
     "color": "blue", 
     "age": "33" 
    }, 
    { 
     "name": "eddie", 
     "color": "green", 
     "age": "77" 
    } 
] 

Voglio la funzione _.groupBy per restituire un oggetto che assomiglia a questo:

[ 
    { 
     color: "blue", 
     users: [ 
      { 
       "name": "jim", 
       "color": "blue", 
       "age": "22" 
      }, 
      { 
       "name": "Sam", 
       "color": "blue", 
       "age": "33" 
      } 
     ] 
    }, 
    { 
     color: "green", 
     users: [ 
      { 
       "name": "eddie", 
       "color": "green", 
       "age": "77" 
      } 
     ] 
    } 
] 

Attualmente sto usando

_.groupBy(a, function(b) { return b.color}) 

che è restituendo questo.

{blue: [{..}], green: [{...}]} 

i raggruppamenti sono corretti, ma mi piacerebbe molto aggiungere le chiavi che voglio (color, users). è possibile utilizzare _.groupBy? o qualche altra utilità LoDash?

risposta

72

Si può fare in questo modo

var result = _.chain(data) 
    .groupBy("color") 
    .pairs() 
    .map(function(currentItem) { 
     return _.object(_.zip(["color", "users"], currentItem)); 
    }) 
    .value(); 
console.log(result); 

Online Demo

Nota: Lodash 4.0 in poi, la funzione .pairs è stato rinominato in _.toPairs()

+0

Molto elegante, ma difficile da avvolgere. Puoi spiegare i passaggi intermedi, in particolare l'accoppiamento e lo zipping (e il doppio zip, poiché '_.object' è un alias per' _.zipObject'). –

+0

Stampa il risultato dopo ogni passaggio. Potrebbe aiutarti a capire meglio. Se hai una domanda specifica per favore fammi sapere. Ti aiuterò con il lodash 3.10.0 – thefourtheye

+2

e alcuni logging per ogni passaggio: http://jsfiddle.net/plantface/WYCF8/171/. È ancora un puzzle, ma ci sto arrivando. Non ho ancora usato '_.zip' e' _.pair' tanto. –

2

vorrei suggerire un approccio diverso, utilizzando my own library potresti farlo in poche righe:

var groupMe = sequence(
    groupBy(pluck('color')), 
    forOwn(function(acc, k, v) { 
    acc.push({colors: k, users: v}); 
    return acc; 
    },[]) 
); 

var result = groupMe(collection); 

Questo sarebbe un po 'difficile con lodash o Underscore perché gli argomenti sono nell'ordine opposto, quindi dovresti usare molto _.partial.

6

Grazie @thefourtheye, il vostro codice è stato di grande aiuto. Ho creato una funzione generica dalla tua soluzione usando la versione 4.5.0 di Lodash.

function groupBy(dataToGroupOn, fieldNameToGroupOn, fieldNameForGroupName, fieldNameForChildren) { 
      var result = _.chain(dataToGroupOn) 
      .groupBy(fieldNameToGroupOn) 
      .toPairs() 
      .map(function (currentItem) { 
       return _.zipObject([fieldNameForGroupName, fieldNameForChildren], currentItem); 
      }) 
      .value(); 
      return result; 
     } 

Per utilizzarlo:

var result = groupBy(data, 'color', 'colorId', 'users'); 

Ecco il violinista aggiornato;

https://jsfiddle.net/sc2L9dby/

24

Non è forse questa semplice?

var result = _(data) 
      .groupBy(x => x.color) 
      .map((value, key) => ({color: key, users: value})) 
      .value(); 
+1

Mi sembra molto più pulito e sembra che stia restituendo gli stessi risultati. Grazie! –

7

altro modo

_.chain(data) 
    .groupBy('color') 
    .map((users, color) => ({ users, color })) 
    .value(); 
+0

Simile alla risposta di @ thefourtheye, ma un po 'più facile da capire –

2

Ecco una versione aggiornata utilizzando lodash 4 e ES6

const result = _.chain(data) 
    .groupBy("color") 
    .toPairs() 
    .map(pair => _.zipObject(['color', 'users'], pair)) 
    .value(); 
0

Esempio groupBy e somma di una colonna utilizzando Lodash 4.17.4

var data = [{ 
       "name": "jim", 
       "color": "blue", 
       "amount": 22 
       }, { 
       "name": "Sam", 
       "color": "blue", 
       "amount": 33 
       }, { 
       "name": "eddie", 
       "color": "green", 
       "amount": 77 
       }]; 

     var result = _(data) 
        .groupBy(x => x.color) 
        .map((value, key) => 
        ({color: key, 
        totalamount: _.sumBy(value,'amount'), 
        users: value})).value(); 

        console.log(result); 
-2

Nel 2017 lo fanno

_.chain(data) 
    .groupBy("color") 
    .toPairs() 
    .map(item => _.zipObject(["color", "users"], item)) 
    .value(); 
-1

ho scritto una funzione che utilizza lodash e restituisce un insieme di dati raggruppati.

let _ = require('lodash'); 

let values = [ 
    { contract_id: "123", id_counterparty: "11" } , 
    { contract_id: "124", id_counterparty: "12" } , 
    { contract_id: "127", id_counterparty: "11" } , 
    { contract_id: "129", id_counterparty: "14" } , 
]; 

let res = _groupObjectsBy('id_counterparty', values, 'groupName', 'values'); 

console.log(res); 


function _groupObjectsBy(propName, objectsArray, outputGroupName, outputValuesName) { 
    let result = _(objectsArray) 
     .groupBy(obj => obj[ propName ]) 
     .map((values, key) => { 
      let obj = {}; 
      obj[ 'groupedBy' ] = propName; 
      obj[ outputGroupName ] = key; 
      obj[ outputValuesName ] = values; 
      return obj; 
     }) 
     .value(); 
     return result; 
} 

Risultato:

[ { groupedBy: 'id_counterparty', 
groupName: '11', 
values: [ [Object], [Object] ] }, 
{ groupedBy: 'id_counterparty', 
groupName: '12', 
values: [ [Object] ] }, 
{ groupedBy: 'id_counterparty', 
groupName: '14', 
values: [ [Object] ] } ] 
+1

Per favore, modifica per spiegare questa risposta. –

2

più alto votato risposta utilizza Lodash funzione _.chain che è considerato una cattiva pratica ora"Why using _.chain is a mistake."

Ecco un fewliner che affronta il problema da programmazione funzionale prospettiva:

import tap from "lodash/fp/tap"; 
import flow from "lodash/fp/flow"; 
import groupBy from "lodash/fp/groupBy"; 

const map = require('lodash/fp/map').convert({ 'cap': false }); 

const result = flow(
     groupBy('color'), 
     map((users, color) => ({color, users})), 
     tap(console.log) 
    )(input) 

Dove input è una matrice che si desidera convertire.

Problemi correlati