लश का उपयोग कर .groupBy। समूहीकृत आउटपुट के लिए अपनी खुद की चाबियाँ कैसे जोड़ें?


104

मेरे पास यह नमूना डेटा एक एपीआई से लौटा है।

मैं लॉडाश का उपयोग कर रहा हूं _.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: [{...}]}

समूह सही हैं, लेकिन मैं वास्तव में उन कुंजियों को जोड़ना चाहूंगा जिन्हें मैं चाहता हूं ( color, users)। क्या यह संभव है _.groupBy? या कुछ अन्य LoDashउपयोगिता?

जवाबों:


140

आप इसे Lodash 4.x में इस तरह कर सकते हैं

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

console.log(
  _.chain(data)
    // Group the elements of Array based on `color` property
    .groupBy("color")
    // `key` is group's name (color), `value` is the array of objects
    .map((value, key) => ({ color: key, users: value }))
    .value()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>


मूल उत्तर

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

ऑनलाइन डेमो

नोट: लोदाश 4.0 बाद में, .pairsफ़ंक्शन का नाम बदल दिया गया है_.toPairs()


बहुत शून्य, लेकिन मेरे सिर को चारों ओर लपेटने के लिए मुश्किल है। क्या आप इसके बीच के चरणों की व्याख्या कर सकते हैं, विशेष रूप से युग्मन और ज़िपिंग (और डबल ज़िप, चूंकि _.objectएक उपनाम है _.zipObject)।
बेनी बोटेमा जूल

3
लॉश 3.10.0 और हर चरण के लिए कुछ लॉगिंग: jsfiddle.net/plantface/WYCF8/171 । यह अभी भी एक पहेली है, लेकिन मैं वहां पहुंच रहा हूं। अभी तक उपयोग नहीं किया गया है _.zipऔर _.pairबहुत कुछ है।
बेनी बोटेमा जूल

12
4. लॉश 4.x में, pairs()विधि अब मौजूद नहीं है। इस उदाहरण का एक अपडेटेड लॉश 4.0 संस्करण है:.chain(data).groupBy('color') .toPairs().map(function (pair) { return _.zipObject(['Name', 'Suppliers'], air); }).value();
एरिक शियरबॉम

5
मुझे लगता है कि लोडश में एक फ़ंक्शन होना चाहिए जो यह बहुत सटीक काम करता है। मुझे लगता है कि उपयोगकर्ता हर समय एक संपत्ति द्वारा वस्तुओं की एक सरणी समूह बनाना चाहेंगे।
एडम क्लेन

1
का उपयोग करना _.chainअब एक बुरा अभ्यास माना जाता है।
पावेल

89

क्या यह इतना आसान नहीं है?

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

4
यह मुझे बहुत साफ लगता है, और वही परिणाम लौटाता है। धन्यवाद!
जेरेमी ए। वेस्ट

3
वाह। यह क्या वाक्य रचना है? पहली बार यह देखते हुए कि आप सरणी को कंस्ट्रक्टर
वी-जेई

यह स्वीकृत उत्तर होना चाहिए। सरल और साफ।
टिआगो स्टापेनहर्स्ट मार्टिन्स


17

उच्चतम मतदान जवाब में लोडाश _.chainफ़ंक्शन का उपयोग किया जाता है जिसे अब एक बुरा अभ्यास माना जाता है "क्यों उपयोग _.chainकरना एक गलती है।"

यहाँ एक बहुवचन है जो कार्यात्मक प्रोग्रामिंग दृष्टिकोण से समस्या का सामना करता है:

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एक सरणी कहां है जिसे आप कनवर्ट करना चाहते हैं।


मैंने यहाँ के flow()बजाय का उपयोग करने की कोशिश की chain(), लेकिन टाइपस्क्रिप्ट के प्रकार की जाँच बस रचनाओं के साथ पागल हो जाती है। मुझे उम्मीद है कि हमारे पास वर्तमान में RxJS में समान स्तर का समर्थन है pipe(), उदाहरण के लिए, लॉश में।
ब्रूनो जेसीएम

मैं वास्तव में आपके नक्शे () सिंटैक्स को पसंद करता हूं, map((users, color) => ({color, users}))इसके बजाय बहुत शांतmap((value, key) => ({ color: key, users: value }))
गिल एप्सटेन

7

धन्यवाद @thefourtheye , आपके कोड ने बहुत मदद की। मैंने लॉडश के 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/


5

यहां लॉश 4 और ईएस 6 का उपयोग करके एक अद्यतन संस्करण है

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

2

मैं एक अलग दृष्टिकोण का सुझाव दूंगा , अपनी खुद की लाइब्रेरी का उपयोग करके आप कुछ लाइनों में ऐसा कर सकते हैं:

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

var result = groupMe(collection);

यह लॉश या अंडरस्कोर के साथ थोड़ा मुश्किल होगा क्योंकि तर्क विपरीत क्रम क्रम में हैं, इसलिए आपको _.partialबहुत अधिक उपयोग करना होगा ।


2

उदाहरण GroupBy और 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);

अच्छा ... और अप टू डेट
पीटर वैन डेर लीली

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.