Underscore.js के साथ ऑब्जेक्ट से खाली गुण / मिथ्या मान निकालें


83

मेरे पास कई गुणों वाली एक वस्तु है। मैं ऐसे किसी भी गुण को दूर करना चाहूंगा, जिसमें मिथ्या मूल्य हैं।

यह compactसरणियों पर प्राप्त किया जा सकता है , लेकिन वस्तुओं के बारे में क्या?


रिपॉजिटरी में इसे कॉपी-पेस्ट करने से बचने के लिए, आप इस घटक को आयात करने के लिए बिट का उपयोग कर सकते हैं (जिसमें 3 परीक्षण पासिंग और एमआईटी लाइसेंस है)। आप इस एनपीएम पैकेज (जो एक छोटे घटक के लिए एक ओवरकिल हो सकता है) की कोशिश कर सकते हैं ।
योनी

जवाबों:


47

आप अपने स्वयं के अंडरस्कोर प्लगइन (मिक्सिन) बना सकते हैं:

_.mixin({
  compactObject: function(o) {
    _.each(o, function(v, k) {
      if(!v) {
        delete o[k];
      }
    });
    return o;
  }
});

और फिर इसे देशी अंडरस्कोर विधि के रूप में उपयोग करें:

var o = _.compactObject({
  foo: 'bar',
  a: 0,
  b: false,
  c: '',
  d: null,
  e: undefined
});

अपडेट करें

जैसा कि @AndreiNeculau ने बताया , यह मिश्रण मूल वस्तु को प्रभावित करता है, जबकि मूल compactअंडरस्कोर विधि सरणी की एक प्रति लौटाती है
इस समस्या को हल करने के लिए और हमारे compactObjectव्यवहार को अधिक पसंद करें जैसे कि यह चचेरा भाई है , यहां एक मामूली अपडेट है:

_.mixin({
  compactObject : function(o) {
     var clone = _.clone(o);
     _.each(clone, function(v, k) {
       if(!v) {
         delete clone[k];
       }
     });
     return clone;
  }
});

1
चूंकि प्रश्न में अंडरस्कोर संदर्भ है, इसलिए यह उल्लेख करना अच्छा होगा कि यह व्यवहार नहीं करता है _.compact। यह केवल सत्य मूल्यों के साथ उथले क्लोन बनाने के बजाय गुणों को हटा देगा। नीचे देखें stackoverflow.com/a/19750822/465684
आंद्रेई नेकुलाउ

@AndreiNeculau तुम सही हो! मुझे लगता है कि पहले याद किया था। देखिये मेरा अपडेटेड जवाब।
gion_13

3
किसी वस्तु के सभी गुणों को पहले क्यों कॉपी करें, फिर उनके माध्यम से लूप करें और नकली लोगों को हटा दें? वह बेपरवाह है। इसके अलावा, deleteआमतौर पर उपयोग को हतोत्साहित किया जाता है क्योंकि यह तुरंत प्रोटोटाइप श्रृंखला से एक ही नाम के गुणों को उजागर करता है और "छिपे हुए वर्ग" (V8) के कारण प्रदर्शन को भी नुकसान पहुंचाता है - ऑब्जेक्ट संरचना को बदलने से इंजन अतिरिक्त काम करता है। सबसे अच्छा और सबसे छोटा समाधान होगा _.pick(o, _.identity)
राडको दिनेव

170

अंडरस्कोर संस्करण 1.7.0 के बाद से, आप उपयोग कर सकते हैं _.pick:

_.pick(sourceObj, _.identity)

व्याख्या

_.pickमूल्यों का चयन करने के लिए दूसरा पैरामीटर एक विधेय कार्य हो सकता है। वे मूल्य जिनके लिए विधेय रिटर्न सत्यता को चुना गया है, और जिन मूल्यों के लिए विधेय रिटर्न नकली है उन्हें नजरअंदाज कर दिया गया है।

लेने _.pick (वस्तु, * कुंजी)

ऑब्जेक्ट की एक प्रति लौटाएं , केवल फ़िल्टर की गई वाइटेल्ड कुंजियों (या मान्य कुंजियों के सरणी) के लिए मान हैं । वैकल्पिक रूप से एक विधेय को इंगित करता है जो इंगित करता है कि कौन सी चाबियाँ लेनी हैं।

_.identityएक सहायक फ़ंक्शन है जो अपना पहला तर्क देता है, जिसका अर्थ है कि यह एक विधेय फ़ंक्शन के रूप में भी काम करता है जो सत्य मूल्यों का चयन करता है और झूठे लोगों को अस्वीकार करता है। अंडरस्कोर लाइब्रेरी भी अन्य विधेयकों के एक समूह के साथ आती है, उदाहरण के लिए _.pick(sourceObj, _.isBoolean)केवल बूलियन गुणों को बनाए रखेगा।

यदि आप इस तकनीक का उपयोग करते हैं, तो आप इसे थोड़ा और अधिक अभिव्यंजक बनाना चाहते हैं:

var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);

अंडरस्कोर संस्करण 1.6.0 भी प्रदान _.pickकिया गया है, लेकिन यह एक श्वेतसूची के बजाय एक समर्पित कार्य को स्वीकार नहीं करता है।


2
_.identityफ़ंक्शन का उल्लेख करने के लिए विशेष धन्यवाद , बहुत आसान है।
ivkremer

9
यह बहुत आसान है! _.omit(sourceObj, _.isUndefined)केवल अपरिभाषित मूल्यों को हटाने के लिए उपयोग करना संभव है (झूठे, अशक्त, 0) की अनुमति देना।
बेन पैटरसन

1
यह भी संभव है pick(obj, Boolean)कि फाल्सी मूल्यों को खत्म करने के लिए किया जाए कि एक ही दृष्टिकोण का उपयोग arr.filter(Boolean)फाल्सी मूल्यों से एक सरणी को साफ करने के लिए किया जा सकता है ...
डेविड चेस

3
_.pick(sourceObj, prop => prop)
ईएस 6

16
लॉश में 4.4.0 _.pickसंपत्ति के नाम के साथ काम करता है, इस कार्यक्षमता के लिए जैसा कि पोस्ट उपयोग में उल्लिखित है_.pickBy
ज़ोबलिन

45

त्वरित 'एन क्लियर: _.omitBy( source, i => !i );

यह एमिल के जवाब के उलटे अंदाज में बताया गया है। इस तरह imho स्पष्ट पढ़ता है; यह अधिक आत्म व्याख्यात्मक है।

यदि आपके पास ES6 की विलासिता नहीं है, तो थोड़ा कम साफ: _.omitBy( source, function(i){return !i;});

वैकल्पिक: _.omitBy( source, _.isEmpty)

सत्यता के _.isEmptyबजाय उपयोग करना , संग्रह से खाली सरणियों और वस्तुओं को भी आसानी से हटा देगा और शायद संख्या और तिथियों को असुविधाजनक रूप से हटा देगा । इस प्रकार परिणाम ओपी के सवाल का सटीक उत्तर नहीं है, हालांकि खाली संग्रह को हटाने के लिए यह उपयोगी हो सकता है।_.identity


8
Lodash 4.0 में, यह कार्यशीलता अब चल रही है omitBylodash.com/docs#omitBy
JackMorrissey

3
मेरा मानना ​​है कि यह वैसा ही है: _.pick(source, i => i); जो नकारने से बचता है
जेफ लोरी

2
@JeffLowery यह और भी बेहतर है, लोदश में, क्योंकि डिफ़ॉल्ट विधेय पहचान समारोह है! _.pickBy(source)बस इतना ही चाहिए।
शिबूमी

नोट: संख्याएँ खाली मानी जाती हैं। _.isEmpty(5) === true। इस प्रकार मान जो संख्याएं हैं, उन्हें गिरा दिया जाएगा।
सर.नाथन स्टासन

21

लॉश के परिवर्तन के साथ ,

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});

23
सफेदी दर्ज करना _.pick (obj, _.identity); छोटा ^ _ ^
दुष्ट

इसके अंतर्गत यह उत्तर या @ दुष्ट की टिप्पणी का उत्तर है।
राडोको दिनेव

2
एक छोटा बदलाव, ऊपर टिप्पणी के आधार पर, हो सकता हैvar compactObject = _.partialRight(_.pick, _.identity);
zaboco


yse, _.pickBy(object)आप सभी की जरूरत है
wdetac

19
Object.keys(o).forEach(function(k) {
    if (!o[k]) {
        delete o[k];
    }
});

1
और एक अंडरस्कोर का उपयोग कर सकते हैं .keysऔर .forEach
फेलिक्स क्लिंग

यह अंडरस्कोर में कैसा लगेगा, फिर? इसे एक साथ रखने की कोशिश ...

+1 यह कमाल का आदमी है। कृपया मुझे forEachJS की विधि का लिंक दें
diEcho


9

आप उथले क्लोन बना सकते हैं:

_(obj).reduce(function(a,v,k){ 
     if(v){ a[k]=v; } 
     return a; 
},{});

5

ऑब्जेक्ट उपयोग के लिए हटाएं।

for(var k in obj){

  if(obj.hasOwnProperty(k) && !obj[k]){
    delete obj[k];
  }
}

क्योंकि वह अंडरस्कोर समाधान चाहता है, आप अंडरस्कोर के तरीकों में से एक का उपयोग करके सरणी पर पुनरावृति कर सकते हैं
gion_13

5

अचानक मुझे ज़रूरत थी कि मैं फ़र्ज़ी तरीके से फ़र्ज़ी लोगों को हटाऊं। आशा है कि ये आपकी मदद करेगा। मैं लोडश का उपयोग कर रहा हूं।

var removeFalsies = function (obj) {
    return _.transform(obj, function (o, v, k) {
        if (v && typeof v === 'object') {
            o[k] = _.removeFalsies(v);
        } else if (v) {
            o[k] = v;
        }
    });
};

_.mixin({ 'removeFalsies': removeFalsies });

तब आप इसका उपयोग कर सकते हैं:

var o = _.removeFalsies({
  foo: 'bar',
  a: 0,
  b: false,
  c: '',
  d: null,
  e: undefined,
  obj: {
    foo: 'bar',
    a: 0,
    b: false,
    c: '',
    d: null,
    e: undefined
  }
});

// {
//   foo: 'bar',
//   obj: {
//     foo: 'bar'
//   }
// }

1

Gion_13 के उत्तर में जोड़ने के लिए:

_.mixin({
  compactObject : function(o) {
     var newObject = {};
     _.each(o, function(v, k) {
       if(v !== null && v !== undefined) {
         newObject[k] = v
       }
     });
     return newObject;
  }
});

यह एक नई वस्तु बनाता है और सब कुछ क्लोन करने और कुंजी-मूल्य जोड़े को हटाने के बजाय कुंजी और मान जोड़ता है। मामूली अंतर।

लेकिन इससे भी महत्वपूर्ण बात, फाल्सी के बजाय अशक्त और अपरिभाषित के लिए स्पष्ट रूप से जांच करता है, जो मूल्य के रूप में झूठे कुंजी-मूल्य जोड़े को हटा देगा।



-1

हालांकि _.compactसरणियों में उपयोग के लिए प्रलेखित है। यह वस्तुओं के लिए भी काम करने लगता है। मैं सिर्फ क्रोम, ओपेरा और फ़ायरफ़ॉक्स कंसोल में निम्नलिखित भाग गया:

var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)

[1, 3, function()]

अद्यतन: जैसा कि नमूना इंगित करता है कि _.compactकिसी वस्तु पर कॉल करने से कुंजी गिर जाएगी और एक संकुचित सरणी वापस आ जाएगी।


1
लेकिन यह अभी भी एक सरणी देता है। चाबी खो जाती है।
तुरादग सिप

1
आप सही हे। क्या मैं अपना उत्तर हटा दूं? या स्टैकओवरफ्लो कुछ और पसंद करता है?
tzvi

2
मैं एक सामुदायिक प्राथमिकता नहीं जानता, लेकिन यदि आप इसे छोड़ने के साथ ठीक हैं तो किसी अन्य व्यक्ति को इसी तरह के उत्तर को जोड़ने से रोकने का मूल्य हो सकता है।
Turadg
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.