जावास्क्रिप्ट में, किसी वस्तु में किसी सदस्य को सशर्त रूप से कैसे जोड़ा जाए?


385

मैं सशर्त रूप से जोड़े गए किसी सदस्य के साथ एक ऑब्जेक्ट बनाना चाहूंगा। सरल दृष्टिकोण है:

var a = {};
if (someCondition)
    a.b = 5;

अब, मैं एक और मुहावरेदार कोड लिखना चाहूंगा। मैं कोशिश कर रहा हूँ:

a = {
    b: (someCondition? 5 : undefined)
};

लेकिन अब, जिसके मूल्य का bएक सदस्य aहै undefined। यह वांछित परिणाम नहीं है।

क्या कोई आसान उपाय है?

अपडेट करें

मैं एक ऐसे समाधान की तलाश में हूं जो कई सदस्यों के साथ सामान्य मामले को संभाल सके।

a = {
  b: (conditionB? 5 : undefined),
  c: (conditionC? 5 : undefined),
  d: (conditionD? 5 : undefined),
  e: (conditionE? 5 : undefined),
  f: (conditionF? 5 : undefined),
  g: (conditionG? 5 : undefined),
 };

23
हाँ वहाँ है; कोड का पहला बिट।
पाओलो बरगीनो

5
यकीन नहीं होता कि मुहावरेदार जावास्क्रिप्ट जैसी कोई चीज होती है ...
माइकल बेर्कोव्स्की

क्या यह वास्तव में मायने रखता है? यदि आप कभी परिभाषित नहीं करते हैं a.b, तो पुनर्प्राप्त a.bकरना undefinedवैसे भी वापस आ जाएगा ।
तैमू

4
@ टिट्टू: जब inऑपरेटर का उपयोग किया जाता है तो यह बात हो सकती है ।

1
अभी के लिए शाब्दिक वस्तुओं में सशर्त गुण होने का कोई तरीका नहीं है, लेकिन मैं चाहता हूं कि वे इसे ES7 में जोड़ दें, यह विशेष रूप से सर्वर साइड प्रोग्रामिंग में बहुत उपयोगी हो सकता है!
अली

जवाबों:


118

शुद्ध जावास्क्रिप्ट में, मैं आपके पहले कोड स्निपेट से अधिक मुहावरेदार कुछ भी नहीं सोच सकता।

यदि, हालांकि, jQuery लाइब्रेरी का उपयोग करना सवाल से बाहर नहीं है, तो $ .extend () को आपकी आवश्यकताओं को पूरा करना चाहिए, क्योंकि दस्तावेज़ कहता है:

अपरिभाषित गुणों की नकल नहीं की जाती है।

इसलिए, आप लिख सकते हैं:

var a = $.extend({}, {
    b: conditionB ? 5 : undefined,
    c: conditionC ? 5 : undefined,
    // and so on...
});

और आपके द्वारा अपेक्षित परिणाम प्राप्त करें (यदि conditionBहै false, तो bमौजूद नहीं होगा a)।


21
वहाँ एक बेहतर तरीका है कि jQuery की आवश्यकता नहीं है। जॅमी हिल के जवाब पर एक नजर।
एंड्रयू रासमुसेन

13
@ और, उस उत्तर के लिए ES6 की आवश्यकता होती है, जो उस समय मौजूद नहीं था जब मैंने अपना लिखा था।
मई को Frédéric Hamidi

शून्य उसी तरह काम करता है? या क्या इसे अपरिभाषित होना चाहिए?
अनु .1000

यह वास्तव में एक गलत जवाब है, क्योंकि यह jQuery का उपयोग करता है और यह टर्नरी स्थिति किसी वस्तु से संपत्ति को नहीं हटाएगी, यह सिर्फ एक संपत्ति को अपरिभाषित के रूप में सेट करेगी। ऐसा करने के सही तरीके के लिए @lagistos जवाब देखें,
अलेक्जेंडर किम

नीचे दिए गए जेमी के उत्तर की जांच करें: stackoverflow.com/a/40560953/10222449
MadMac

867

मुझे लगता है कि @InspiredJW ने ES5 के साथ ऐसा किया था, और @trincot ने बताया कि es6 का उपयोग करना एक बेहतर तरीका है। लेकिन हम प्रसार ऑपरेटर और तार्किक और शॉर्ट सर्किट मूल्यांकन का उपयोग करके थोड़ी अधिक चीनी जोड़ सकते हैं:

const a = {
   ...(someCondition && {b: 5})
}

2
मुझे यकीन नहीं है कि यह सही है, प्रस्ताव में कहा गया है Null/Undefined Are Ignored, यह नहीं कहता कि falseइसे अनदेखा किया गया है। ट्रांसपॉयलर वर्तमान में इसके माध्यम से अनुमति दे सकते हैं, लेकिन क्या यह आज्ञाकारी है? निम्नलिखित होना चाहिए, {...someCondition ? {b: 5} : null}लेकिन कॉम्पैक्ट के रूप में नहीं है।
बेंजामिन डोबेल

23
मैंने पूछा कि क्या यह उन लोगों के लिए वैध था जिन्होंने प्रस्ताव फैलाया था और उन्होंने कहा कि यह ठीक है। github.com/tc39/proposal-object-rest-spread/issues/45 , सीसी @BenjaminDobell
김민준

73
@ एलन प्रसार ऑपरेटर शॉर्टहैंड की तरह होता है Object.assignऔर इसमें && ऑपरेटर की तुलना में कम पूर्वता होती है। यह संपत्ति (बूलियन, अशक्त, अपरिभाषित, संख्या) के बिना मूल्य की उपेक्षा करता है, और ...जगह के बाद ऑब्जेक्ट के सभी गुणों को जोड़ता है। याद रखें कि &&ऑपरेटर सही मूल्य लौटाता है अगर सही है, या गलत है। इसलिए यदि someConditionयह सही है, {b : 5}तो ...ऑपरेटर को पास कर दिया जाएगा , जिसके परिणामस्वरूप संपत्ति bको aमूल्य के साथ जोड़ा जाएगा 5। है someConditionगलत है, falseको दे दिया जाएगा ...ऑपरेटर। कुछ भी नहीं मिला। यह चतुर है। मुझे यह पसंद है।
फेलिक्स ब्रुनेट

11
शानदार उत्तर, लेकिन स्थिति और परिणामी वस्तु को कोष्ठक में फैलाए जाने से इस उदाहरण की पठनीयता में काफी सुधार होगा। हर कोई जेएस ऑपरेटर की मिसाल को दिल से याद नहीं करता।
न्यूरोट्रांसमीटर

6
केवल अन्य समस्या यह है कि आप इसका उपयोग झूठे बूलियंस के लिए नहीं कर सकते।
ggb667

92

EcmaScript2015 के साथ आप उपयोग कर सकते हैं Object.assign:

Object.assign(a, conditionB ? { b: 1 } : null,
                 conditionC ? { c: 2 } : null,
                 conditionD ? { d: 3 } : null);

कुछ टिप्पणी:

  • Object.assign पहले तर्क को जगह में संशोधित करता है, लेकिन यह अपडेट की गई वस्तु को भी लौटाता है: इसलिए आप इस विधि का उपयोग एक बड़ी अभिव्यक्ति में कर सकते हैं जो ऑब्जेक्ट को और अधिक हेरफेर करता है।
  • nullआप के बजाय undefinedया पारित कर सकते हैं {}, एक ही परिणाम के साथ। आप 0इसके बजाय प्रदान भी कर सकते हैं , क्योंकि आदिम मूल्य लिपटे हुए हैं, और Numberउनके पास स्वयं के गुण नहीं हैं

और भी संक्षिप्त

दूसरी बात आगे ले, तो आप इसे इस प्रकार है (जैसा कि @Jamie उठाई बाहर है), के रूप में falsy मूल्यों कोई खुद गणनीय गुण होते हैं (छोटा हो सकता है false, 0, NaN, null, undefined, '', सिवाय document.all):

Object.assign(a, conditionB && { b: 1 },
                 conditionC && { c: 2 },
                 conditionD && { d: 3 });


1
मैं प्रारंभिक समाधान पसंद करता हूं: यह पता लगाने में आसान है कि क्या चल रहा है - मुझे यकीन नहीं होगा कि एक आदिम मूल्य के साथ क्या होता है (कम से कम कल्पना को देखे बिना नहीं)।
एक्सल रस्शमेयर

1
मुझे आशुलिपि तर्क को सरल बनाने वाले शॉर्टहैंड से प्यार है। मुझे ठीक इसी की आवश्यकता थी। धन्यवाद!
TheUtherSide

80
const obj = {
   ...(condition) && {someprop: propvalue},
   ...otherprops
}

लाइव डेमो:

const obj = {
  ...(true) && {someprop: 42},
  ...(false) && {nonprop: "foo"},
  ...({}) && {tricky: "hello"},
}

console.log(obj);


7
हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
राल्फ स्टबनर


अगर कंडोम मैच नहीं करता है तो यह अपरिभाषित वापस आ जाएगा।
मुस्तकेम के

2
यह काम करता है, और इसमें किसी भी अन्य आईएमओ के उत्तर की तुलना में अच्छे वाक्यविन्यास हैं।
रीड

1
संक्षिप्त विवरण इस तरह से है: "..." प्रसार ऑपरेटर ऑब्जेक्ट शाब्दिक deconstructs और इसे "obj" में जोड़ता है जैसे कि इस मामले में ... (सत्य) और& {someprop: 42}, संपूर्ण शब्द जो डिकंस्ट्रक्ट किया जाना है "(सच्चा) && {someprop: 42}", इस मामले में बूलियन सही है और यह शब्द केवल {someprop: 42} पैदावार देता है, जिसे बाद में विघटित कर obj में जोड़ दिया जाता है। अगर बूलियन इसके बजाय झूठा है, तो यह शब्द सिर्फ झूठा होगा, और कुछ भी deconstructed नहीं होगा और obj में जोड़ा जाएगा
Qiong Wu

50

बूलियन के साथ प्रसार सिंटैक्स का उपयोग करना (जैसा कि यहां बताया गया है) वैध सिंटैक्स नहीं है। स्प्रेड का उपयोग केवल पुनरावृत्तियों के साथ किया जा सकता है ।

मैं निम्नलिखित सुझाव देता हूं:

const a = {
   ...(someCondition? {b: 5}: {} )
}

2
@HossamMourad, यह नहीं होना चाहिए, क्योंकि सुझाए गए कोड का उपयोग 2 साल पहले पोस्ट किए गए उत्तर में पहले से ही किया गया था। और पहली टिप्पणी झूठी है। यह मान्य वाक्यविन्यास है:{...false}
trincot

1
@ इताई, यह सच नहीं है; प्रसार सिंटैक्स के साथ उपयोग किए जाने पर आदिम मान लिपटे होते हैं। {...false}मान्य सिंटैक्स है।
त्रिनकोट

@ ट्रैक, क्या आप संदर्भ प्रदान कर सकते हैं?
इताई नोआम

3
EcmaScript 2018 भाषा विनिर्देश, खंड 12.2.6 (.8) निर्दिष्ट करता CopyDataPropertiesहै जो मूल्य पर ( falseइस मामले में) किया जाता है। इसमें एक आदिम (अनुभाग 7.3.23, 7.1.13) बॉक्सिंग शामिल है। आपको MDN के लिंक को कोष्ठक में इस "अपवाद" का उल्लेख है।
19 को

एक संदर्भ के रूप में, इस पोस्ट को भी देखें जहां मैं इसी विषय पर विस्तार करता हूं।
19

26

एन्हांस्ड ऑब्जेक्ट प्रॉपर्टी का उपयोग करने के बारे में क्या है और केवल संपत्ति सेट करें यदि यह सत्य है, उदाहरण के लिए:

[isConditionTrue() && 'propertyName']: 'propertyValue'

इसलिए यदि शर्त पूरी नहीं होती है तो यह पसंदीदा संपत्ति नहीं बनाता है और इस तरह आप इसे त्याग सकते हैं। देखें: http://es6-features.org/#ComputedPropertyNames

अद्यतन: वस्तु लेख शाब्दिक और सरणियों ( http://2ality.com/2017/04/conditional-literal-entries.html ) के अंदर सशर्त रूप से प्रविष्टियाँ जोड़ने के बारे में अपने ब्लॉग लेख में एक्सल रस्शमेयर के दृष्टिकोण का पालन करना और भी बेहतर है। )

const arr = [
  ...(isConditionTrue() ? [{
    key: 'value'
  }] : [])
];

const obj = {
  ...(isConditionTrue() ? {key: 'value'} : {})
};

काफी ने मेरी बहुत मदद की।


1
यह लगभग काम करेगा। समस्या यह है कि यह एक अतिरिक्त falseकुंजी जोड़ देगा । उदाहरण के लिए, {[true && 'a']: 17, [false && 'b']: 42}है{a:17, false: 42}
viebel

3
मुझे और अधिक संक्षिप्त तरीका मिला: ...isConditionTrue() && { propertyName: 'propertyValue' }
दिमित्री रिफ़्शिनडर

बेहतर तरीका: ... (isConditionTrue ()? {Key: 'value'}: {})
दिमित्री Reifschneider

Axel Rauschmayer ब्लॉग लिंक यह जवाब देता है। लेख में "... इंसर्टआईएफ (कॉन्ड, 'ए') उदाहरण बिल्कुल वही है जो मैं खोज रहा था। धन्यवाद
जोसेफ सिम्पसन


5

यदि लक्ष्य स्व-निहित है और ब्रेसिज़ के एक सेट के भीतर होना है, तो आप यह कोशिश कर सकते हैं:

var a = new function () {
    if (conditionB)
        this.b = 5;

    if (conditionC)
        this.c = 5;

    if (conditionD)
        this.d = 5;
};

5

यदि आप इस सर्वर साइड (jquery के बिना) करना चाहते हैं, तो आप 4.3.0 का उपयोग कर सकते हैं:

a = _.pickBy({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));

और यह काम 3.10.1 दर्ज करवाता है

a = _.pick({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined));

ES6 में दर्ज करने की कोई आवश्यकता नहीं है।
डैन डस्केल्सस्कु

5
var a = {
    ...(condition ? {b: 1} : '') // if condition is true 'b' will be added.
}

मुझे उम्मीद है कि यह शर्त के आधार पर एक प्रविष्टि जोड़ने के लिए बहुत कुशल तरीका है। सशर्त रूप से किसी ऑब्जेक्ट शाब्दिक के अंदर प्रविष्टियों को जोड़ने के बारे में अधिक जानकारी के लिए।


3
[...condition?'':['item']]यह स्ट्रिंग आइटम को सरणी में जोड़ देगा
वेउ


1
@DanDascalescu जेमी हिल का जवाब मेरे जवाब से बेहतर है, मैंने उस तरह से नहीं सोचा था और मैं एक टर्नेरी-ऑपरेटर आदमी था।
मधनकुमार

4

यह लंबे समय से उत्तर दिया गया है, लेकिन अन्य विचारों को देखते हुए मैं कुछ दिलचस्प व्युत्पन्न के साथ आया हूं:

अपरिभाषित मूल्यों को एक ही संपत्ति में असाइन करें और बाद में हटा दें

एक अनाम निर्माता का उपयोग करके अपनी वस्तु बनाएं और हमेशा अपरिभाषित सदस्यों को उसी डमी सदस्य को असाइन करें जिसे आप बहुत अंत में हटाते हैं। यह आपको अंत में प्रति सदस्य + 1 अतिरिक्त लाइन एक सिंगल लाइन (नॉट कॉम्प्लेक्स आई होप) देगा।

var a = new function() {
    this.AlwaysPresent = 1;
    this[conditionA ? "a" : "undef"] = valueA;
    this[conditionB ? "b" : "undef"] = valueB;
    this[conditionC ? "c" : "undef"] = valueC;
    this[conditionD ? "d" : "undef"] = valueD;
    ...
    delete this.undef;
};

4

आप बिना किसी शर्त के अपने सभी अपरिभाषित मूल्यों को जोड़ सकते हैं और फिर JSON.stringifyउन सभी को निकालने के लिए उपयोग कर सकते हैं:

const person = {
  name: undefined,
  age: 22,
  height: null
}

const cleaned = JSON.parse(JSON.stringify(person));

// Contents of cleaned:

// cleaned = {
//   age: 22,
//   height: null
// }

2

मैं यह करूँगा

var a = someCondition ? { b: 5 } : {};

एक पंक्ति कोड संस्करण के साथ संपादित किया गया


अगर हालत झूठी है, एक नग्न है, जो सही नहीं है।
bingjie2680

@ bingjie2680 ऐसा नहीं है कि स्पष्ट यह क्या एक होना चाहिए जब someCondition गलत है। मैंने अभी मान लिया a = undefined। इसे आसानी से बदला जा सकता है return { b: undefined };: /
jwchang

@ bingjie2680 तब यह भाग return {};में होना चाहिएelse
jwchang

1
यह वास्तव में नहीं है कि आप क्या करेंगे ... क्या यह है? मेरा मतलब है कि अगर आप पूरे शाब्दिक वाक्य रचना को सशर्त बनाते हैं, तो आप सशर्त ऑपरेटर का उपयोग क्यों नहीं करेंगे? a = condition ? {b:5} : undefined;

3
बधाई हो, आपने बिना किसी लाभ के 7-लाइन फ़ंक्शन में तीन मृत-सरल रेखाओं को बदल दिया। नहीं, एक अनाम फ़ंक्शन का उपयोग करना एक लाभ नहीं है।

2

लॉश लाइब्रेरी का उपयोग करके, आप _.omitBy का उपयोग कर सकते हैं

var a = _.omitBy({
    b: conditionB ? 4 : undefined,
    c: conditionC ? 5 : undefined,
}, _.IsUndefined)

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

var a = _.omitBy({
    b: req.body.optionalA,  //if undefined, will be removed
    c: req.body.optionalB,
}, _.IsUndefined)

0

मुझे लगता है कि सशर्त रूप से सदस्यों को जोड़ने के लिए आपका पहला दृष्टिकोण पूरी तरह से ठीक है। मैं वास्तव में एक सदस्य है के लिए इच्छुक नहीं से सहमत नहीं bकी aऔर मान एक undefined। ऑपरेटर के साथ लूप के undefinedउपयोग के साथ चेक जोड़ना काफी सरल है । लेकिन वैसे भी, आप आसानी से सदस्यों को फ़िल्टर करने के लिए एक फ़ंक्शन लिख सकते हैं ।forinundefined

var filterUndefined = function(obj) {
  var ret = {};
  for (var key in obj) {
    var value = obj[key];
    if (obj.hasOwnProperty(key) && value !== undefined) {
      ret[key] = value;
    }
  }
  return ret;
};

var a = filterUndefined({
  b: (conditionB? 5 : undefined),
  c: (conditionC? 5 : undefined),
  d: (conditionD? 5 : undefined),
  e: (conditionE? 5 : undefined),
  f: (conditionF? 5 : undefined),
  g: (conditionG? 5 : undefined),
});

आप deleteऑब्जेक्ट को जगह में संपादित करने के लिए ऑपरेटर का उपयोग भी कर सकते हैं ।


0

किसी वस्तु में लपेटना

कुछ इस तरह से क्लीनर है

 const obj = {
   X: 'dataX',
   Y: 'dataY',
   //...
 }

 const list = {
   A: true && 'dataA',
   B: false && 'dataB',
   C: 'A' != 'B' && 'dataC',
   D: 2000 < 100 && 'dataD',
   // E: conditionE && 'dataE',
   // F: conditionF && 'dataF',
   //...
 }

 Object.keys(list).map(prop => list[prop] ? obj[prop] = list[prop] : null)

एक सरणी में लपेटें

या यदि आप जेमी हिल की विधि का उपयोग करना चाहते हैं और शर्तों की एक लंबी सूची है तो आपको ...कई बार सिंटैक्स लिखना होगा । इसे थोड़ा क्लीनर बनाने के लिए, आप उन्हें केवल एक सरणी में लपेट सकते हैं, फिर reduce()उन्हें एक ही वस्तु के रूप में वापस करने के लिए उपयोग कर सकते हैं।

const obj = {
  X: 'dataX',
  Y: 'dataY',
  //...

...[
  true && { A: 'dataA'},
  false && { B: 'dataB'},
  'A' != 'B' && { C: 'dataC'},
  2000 < 100 && { D: 'dataD'},
  // conditionE && { E: 'dataE'},
  // conditionF && { F: 'dataF'},
  //...

 ].reduce(( v1, v2 ) => ({ ...v1, ...v2 }))
}

या map()फ़ंक्शन का उपयोग कर रहा है

const obj = {
  X: 'dataX',
  Y: 'dataY',
  //...
}

const array = [
  true && { A: 'dataA'},
  false &&  { B: 'dataB'},
  'A' != 'B' && { C: 'dataC'},
  2000 < 100 && { D: 'dataD'},
  // conditionE && { E: 'dataE'},
  // conditionF && { F: 'dataF'},
  //...

 ].map(val => Object.assign(obj, val))

0

यह सबसे रसीला समाधान है जिसके साथ मैं आ सकता हूं:

var a = {};
conditionB && a.b = 5;
conditionC && a.c = 5;
conditionD && a.d = 5;
// ...

-1

लॉश लाइब्रेरी का उपयोग करके, आप _.merge का उपयोग कर सकते हैं

var a = _.merge({}, {
    b: conditionB ? 4 : undefined,
    c: conditionC ? 5 : undefined,
})
  1. अगर conditionB है false& conditionC है true, तोa = { c: 5 }
  2. यदि दोनों कंडीशन और कंडीशन सी हैं true, तोa = { b: 4, c: 5 }
  3. यदि दोनों कंडीशन और कंडीशन सी हैं false, तोa = {}

मुझे एक अलग परिणाम मिलता है। मैं उपयोग कर रहा हूं lodash@^4.0.0undefinedमेरे मामले में शामिल किए जा रहे हैं।
जॉनीक्यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.