2014-05-12 44 views
47

我有從API返回此示例數據。使用lodash .groupBy。如何爲分組輸出添加自己的密鑰?

我使用Lodash的_.groupBy將數據轉換爲我可以更好地使用的對象。 返回的原始數據是這樣的:

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

我想_.groupBy函數返回一個對象,它看起來像這樣:

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

目前我使用

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

這是返回這個。

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

的分組是正確的,但我真的想補充我想要的鍵(colorusers)。這可能使用_.groupBy?或其他LoDash實用程序?

回答

72

你可以像下面這樣做

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

Online Demo

注: Lodash 4.0起,.pairs功能已重命名爲_.toPairs()

+0

非常漂亮,但很難包住我的頭。你能解釋一下兩者之間的步驟,特別是配對和壓縮(和雙拉鍊,因爲'_.object'是'_.zipObject'的別名)。 –

+0

每個步驟後打印結果。它可以幫助你更好地理解。如果您有具體問題,請告訴我。我會幫你用 – thefourtheye

+2

lodash 3.10.0和每一步的一些日誌記錄:http://jsfiddle.net/plantface/WYCF8/171/。這仍然是一個難題,但我到了那裏。還沒有使用'_.zip'和'_.pair'。 –

2

我會建議不同的方法,使用my own library你可以在幾行內做到這一點:

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

var result = groupMe(collection); 

這與lodash或Underscore會有點困難,因爲參數的順序是相反的,所以你必須使用_.partial很多。

6

謝謝@thefourtheye,你的代碼很有幫助。 我使用Lodash 4.5.0版本從您的解決方案創建了一個通用函數。

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

要使用它:

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

這裏是更新的小提琴手;

https://jsfiddle.net/sc2L9dby/

24

是不是這個簡單?

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

這對我來說似乎更清潔,並且似乎返回了相同的結果。謝謝! –

7

另一種方式

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

與@ thefourtheye的答案類似,但有點容易理解 –

2

這裏是使用利用Lodash 4.17列lodash 4和ES6

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

例GROUPBY和總和的更新版本。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

在2017年這樣做

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

我寫了一個使用lodash並返回一個分組數據的功能。

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; 
} 

結果:

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

請編輯以解釋此答案。 –

2

最高的投票答案使用這被認爲是現在一種不好的做法"Why using _.chain is a mistake."

這裏Lodash _.chain功能,從函數式編程接近問題fewliner透視圖:

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) 

其中input是您要轉換的數組。

相關問題