जावास्क्रिप्ट में किसी ऑब्जेक्ट से रिक्त विशेषताएँ निकालें


265

मैं उन सभी विशेषताओं को कैसे हटाऊं जो एक जावास्क्रिप्ट ऑब्जेक्ट में undefinedया हैं null?

(प्रश्न अर्रे के लिए इस के समान है )


19
अत्यधिक सुझाव दें कि लोग शीर्ष-रैंक को अनदेखा करें और यहां ES6 / ES7 संस्करणों पर जाएं, stackoverflow.com/a/38340730/124486
इवान कैरोल

2
इसके अलावा ES6 एक लाइनर बिना ऑब्जेक्ट को बदले में यहां है: stackoverflow.com/a/57625661/1602301
मुर्गियां

जवाबों:


184

आप ऑब्जेक्ट के माध्यम से लूप कर सकते हैं:

var test = {
    test1 : null,
    test2 : 'somestring',
    test3 : 3,
}

function clean(obj) {
  for (var propName in obj) { 
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

clean(test);

यदि आप इस संपत्ति को हटाने के बारे में चिंतित हैं तो ऑब्जेक्ट की प्रॉपर टाइप श्रृंखला नहीं चल रही है, आप यह भी कर सकते हैं:

function clean(obj) {
  var propNames = Object.getOwnPropertyNames(obj);
  for (var i = 0; i < propNames.length; i++) {
    var propName = propNames[i];
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

अशक्त बनाम अशक्त पर कुछ नोट:

test.test1 === null; // true
test.test1 == null; // true

test.notaprop === null; // false
test.notaprop == null; // true

test.notaprop === undefined; // true
test.notaprop == undefined; // true

2
एक त्वरित सुधार जोड़ा गया। अघोषित "i" वेरिएबल बाहरी दायरे में लीक हो जाता अगर इस स्निपेट को कभी किसी फंक्शन में इस्तेमाल किया जाता।
एरिक गुयेन

4
आप परीक्षण को आसान बना सकते हैं (परीक्षण [i] === null || परीक्षण [i] === अपरिभाषित) (परीक्षण [i] == नल)
jaf0

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

1
@GerardoLima, हाँ। मैं यह मानकर चल रहा था कि यह सब एक समारोह में लिपटा होगा। मेरा मतलब था (यह मानते हुए कि यह सब एक फ़ंक्शन के साथ लिपटा हुआ है) यह है कि आपको संस्करण घोषणा की आवश्यकता है या मैं फ़ंक्शन दायरे के बाहर भी लीक कर दूंगा।
एरिक गुयेन

यह आदिम वस्तु के प्रोटोटाइप के माध्यम से भी लूप करेगा - जो ज्यादातर मामलों में वांछित नहीं है। stackoverflow.com/a/2869372/1612318
रोटारटी

427

कुछ ES6 / ES2015 का उपयोग करना :

1) बिना असाइनमेंट के आइटम इनलाइन को हटाने के लिए एक सरल एक-लाइनर :

Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);

jsbin

2) इस उदाहरण को हटा दिया गया ...

3) एक समारोह के रूप में लिखा गया पहला उदाहरण:

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => obj[key] == null && delete obj[key]);
};

jsbin

4) यह फ़ंक्शन नेस्टेड ऑब्जेक्ट्स से भी आइटम को हटाने के लिए पुनरावर्तन का उपयोग करता है :

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") removeEmpty(obj[key]); // recurse
    else if (obj[key] == null) delete obj[key]; // delete
  });
};

jsbin

4 बी) यह 4 के समान है), लेकिन सीधे स्रोत ऑब्जेक्ट को म्यूट करने के बजाय, यह एक नई वस्तु लौटाता है।

const removeEmpty = obj => {
  const newObj = {};

  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") {
      newObj[key] = removeEmpty(obj[key]); // recurse
    } else if (obj[key] != null) {
      newObj[key] = obj[key]; // copy value
    }
  });

  return newObj;
};

5) @ MichaelJ.Zoidl के उत्तर का उपयोग कर और के आधार पर 4 बी के लिए एक कार्यात्मक दृष्टिकोण) । यह एक नई वस्तु देता है:filter()reduce()

const removeEmpty = obj =>
  Object.keys(obj)
    .filter(k => obj[k] != null) // Remove undef. and null.
    .reduce(
      (newObj, k) =>
        typeof obj[k] === "object"
          ? { ...newObj, [k]: removeEmpty(obj[k]) } // Recurse.
          : { ...newObj, [k]: obj[k] }, // Copy value.
      {}
    );

jsbin

6) 4 के समान) लेकिन ES7 / 2016 के साथ Object.entries()

const removeEmpty = (obj) => 
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') removeEmpty(val)
    else if (val == null) delete obj[key]
})

5 बी) एक और कार्यात्मक संस्करण जो पुनरावृत्ति का उपयोग करता है और ES2019 के साथ एक नई वस्तु देता है Object.fromEntries():

const removeEmpty = obj =>
  Object.fromEntries(
    Object.entries(obj)
      .filter(([k, v]) => v != null)
      .map(([k, v]) => (typeof v === "object" ? [k, removeEmpty(v)] : [k, v]))
  );

7) 4 के रूप में भी) लेकिन सादे ES5 में :

function removeEmpty(obj) {
  Object.keys(obj).forEach(function(key) {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
    else if (obj[key] == null) delete obj[key]
  });
};

jsbin


3
@AugustinRiedinger जब मुझे एक लाइन-ब्रेक और एक संक्षिप्त नाम के बीच फैसला करना होता है, तो मुझे कभी-कभी संक्षिप्त नाम मिलता है अगर मुझे लगता है कि संक्षिप्त नाम कम बुराई है। 5 में कोड) के बारे में तर्क करना मुश्किल नहीं है और यह एक ऐसा फ़ंक्शन है जो keysएक से खाली निकालता है object, इसलिए oऔर kस्पष्ट हैं। लेकिन मुझे लगता है कि यह स्वाद की बात है।
रोटारटी

3
ES5 स्वाद के साथ पहला संस्करण:Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
न्यूरोट्रांसमीटर

1
एक पंक्ति, बिना कार्य:Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})
पॉल स्लम

7
चूंकि हम पूरी तरह से प्रयास कर रहे हैं, इसलिए एक अपरिवर्तनीय समाधान को देखना अच्छा हो सकता है। ये स्रोत ऑब्जेक्ट को म्यूट कर रहे हैं और धोखे से उस ऑब्जेक्ट को वापस कर रहे हैं जो वास्तव में अनावश्यक है क्योंकि ऑब्जेक्ट को उत्परिवर्तित किया गया है। शुरुआती लौटे ऑब्जेक्ट वैल्यू पर कब्जा कर लेंगे और आश्चर्य करेंगे कि उनके स्रोत ऑब्जेक्ट को भी क्यों संशोधित किया गया है।
माइक मैक्लिन

2
5) सरणियों के साथ काम नहीं करता है (Object.keys सरणी स्थिति संख्या को तत्वों के लिए कुंजी के रूप में लौटाएगा)। संभवतः अन्य लोगों को यह समस्या है, लेकिन मुझे यह पता चला जब परीक्षण 5.
इलको

95

यदि आप लॉश या अंडरस्कोर का उपयोग कर रहे हैं। यहाँ एक सरल उपाय है:

var obj = {name: 'John', age: null};

var compacted = _.pickBy(obj);

यह केवल लॉश 4, प्री लॉश 4 या अंडरस्कोर.जेएस, उपयोग के साथ काम करेगा _.pick(obj, _.identity);


1
प्रतिभाशाली! धन्यवाद! FYI करें, जो मेरे लिए स्पष्ट नहीं था वह यह है कि आप इसे इस तरह भी इस्तेमाल कर सकते हैं: foo ()। तब (_। PickByy); // खाली परिणामों को
छानना

29
ध्यान दें कि यह वांछित परिणाम नहीं होगा यदि ऑब्जेक्ट में 0 या खाली स्ट्रिंग्स जैसे गलत मान हैं। तब _.omit(obj, _.isUndefined)बेहतर है।
जेएचएच

5
@ जेएचएच _.isUndefinedनल को नहीं छोड़ता है, _.omitBy(obj, _.isNil)दोनों को छोड़ने के लिए उपयोग करें undefinedऔरnull
लुकाज़ विकटोर

@LukaszWiktor सही, सवाल अपरिभाषित या अशक्त के लिए पूछा था।
JHH

85

ES6 + के लिए सबसे छोटा एक लाइनर

सभी falsy मान फ़िल्टर ( "", 0, false, null, undefined)

Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})

फ़िल्टर nullऔर undefinedमान:

Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})

केवल फ़िल्टर करें null

Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})

केवल फ़िल्टर करें undefined

Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})

पुनरावर्ती समाधान: फिल्टर nullऔरundefined

वस्तुओं के लिए:

const cleanEmpty = obj => Object.entries(obj)
        .map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
        .reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});

ऑब्जेक्ट और एरेज़ के लिए:

const cleanEmpty = obj => {
  if (Array.isArray(obj)) { 
    return obj
        .map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
        .filter(v => !(v == null)); 
  } else { 
    return Object.entries(obj)
        .map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
        .reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
  } 
}

10
यह एकमात्र उत्तर होना चाहिए! इनमें से प्रत्येक स्निपेट एक नई वस्तु उत्पन्न करेगा जहां पुराने को उत्परिवर्तित नहीं किया जाएगा। यह बेहतर है! एक छोटी सी टिप्पणी करता है, तो आप का उपयोग सिर्फ v == nullआप के खिलाफ जाँच करेगा undefinedऔर null
मेगाजिन

cleanEmptyrecursve समाधान एक खाली वस्तु वापस आ जाएगी {}दिनांक वस्तुओं के लिए
एम्मानुएल एन.के.

एक लाइनर में थोड़ी अधिक सुगमता उन्हें भयानक बना देगी !!
जार्डिलियर

39

अगर किसी को ओवेन (और एरिक) के उत्तर के पुनरावर्ती संस्करण की आवश्यकता है, तो यह यहां है:

/**
 * Delete all null (or undefined) properties from an object.
 * Set 'recurse' to true if you also want to delete properties in nested objects.
 */
function delete_null_properties(test, recurse) {
    for (var i in test) {
        if (test[i] === null) {
            delete test[i];
        } else if (recurse && typeof test[i] === 'object') {
            delete_null_properties(test[i], recurse);
        }
    }
}

लूप शुरू होने के बाद, आपको यह देखना चाहिए कि वस्तु hasOwnPropertyका उपयोग कर रहा हैif(test.hasOwnProperty(i)) { ... }
Augie Gardner

@AugieGardner मैं उत्सुक हूं कि आप इसे क्यों जांचना चाहते हैं - यदि आप चाहें तो कृपया इसे समझाएं। (क्या यह विरासत में मिली संपत्तियों की जाँच को नहीं रोक पाएगा?)
वूम्स

24

JSON.stringify अपरिभाषित कुंजी निकालता है।

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}

यह मेरे लिए एक गहरी वस्तु के लिए काम नहीं करता था, लेकिन ऊपर Wumm का जवाब था।
सुमन

1
यदि आपको प्रतिस्थापन फ़ंक्शन का उपयोग nullकरने की आवश्यकता है undefined, तो अधिक जानकारी के लिए इस उत्तर को देखें: stackoverflow.com/questions/286141/…
Hooman Askari

बस ध्यान रखें कि यह nullमूल्यों को दूर नहीं करता है । कोशिश करो: let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }और फिर console.log(removeUndefined(a))। सवाल था undefinedऔर nullमूल्यों का।
शाम

13

आप शायद deleteकीवर्ड की तलाश कर रहे हैं ।

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;

4
यह वही है जो वह ऊपर कर रहा है, यह अभी भी ऑब्जेक्ट में अपरिभाषित छोड़ देता है।
जोश बेदो

10

फ़िल्टर किए गए मानों nullऔर undefinedमानों को वापस करने के लिए सरलतम लॉडश समाधान ।

_.omitBy(obj, _.isNil)


यह अब तक का सबसे साफ समाधान है!
जी मोक

9

आप JSON.stringifyइसके प्रतिकृति पैरामीटर के संयोजन का उपयोग कर सकते हैं , और JSON.parseइसे एक वस्तु में बदल सकते हैं। इस पद्धति का उपयोग करने का अर्थ यह भी है कि प्रतिस्थापन नेस्टेड ऑब्जेक्ट्स के भीतर सभी नेस्टेड कुंजियों के लिए किया जाता है।

उदाहरण वस्तु

var exampleObject = {
  string: 'value',
  emptyString: '',
  integer: 0,
  nullValue: null,
  array: [1, 2, 3],
  object: {
    string: 'value',
    emptyString: '',
    integer: 0,
    nullValue: null,
    array: [1, 2, 3]
  },
  arrayOfObjects: [
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    },
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    }
  ]
};

पुनरावृत्ति करने वाला कार्य

function replaceUndefinedOrNull(key, value) {
  if (value === null || value === undefined) {
    return undefined;
  }

  return value;
}

ऑब्जेक्ट को साफ़ करें

exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);

कोड उदाहरण


6

रम्दा # pickBy का उपयोग करके आप सभी को हटा देंगे null, undefinedऔर falseमान:

const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)

मानमनरो ने बताया कि falseमानों का उपयोग करने के लिए isNil():

const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)

1
(v) => !R.isNil(v)शायद ओपी के प्रश्न के लिए एक बेहतर विकल्प है, यह देखते हुए कि falseया अन्य गलत मूल्यों को भी खारिज कर दिया जाएगाR.identity
मैनरो

6

कार्यात्मक और अपरिवर्तनीय दृष्टिकोण, .filterआवश्यकता से अधिक वस्तुओं का निर्माण किए बिना और बिना

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})

बहुत संक्षिप्त जवाब। भी जोड़ने के लिए अशक्त जांच अभी की जगह obj[key] === undefinedके लिएobj[key] === undefined || obj[key] === null
user3658510

उपरोक्त दृष्टिकोण की थोड़ी भिन्नता: आप भी सच में obj संपत्ति में इस तरह से फैल सकता हैconst omitFalsy = obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...(obj[key] && { [key]: obj[key] }) }), {});
केविन के।

5

आप !हालत के साथ कम कर सकते हैं

var r = {a: null, b: undefined, c:1};
for(var k in r)
   if(!r[k]) delete r[k];

उपयोग में याद रखें: जैसा कि @semicolor टिप्पणियों में घोषणा की गई है: यह भी गुण हटा देगा यदि मान एक रिक्त स्ट्रिंग, गलत या शून्य है


11
यदि मान रिक्त स्ट्रिंग, गलत या शून्य है, तो यह गुण भी हटा देगा।
अर्धविराम

3
यह एक जेन्स अनुरोध से अवांछित क्षेत्रों को हटाने के लिए वास्तव में मैं क्या देख रहा था। धन्यवाद!
फ़रोज़न

के [null, undefined].includes(r[k])बजाय का उपयोग करें !r[k]
selmansamet

5

छोटा ईएस 6 शुद्ध समाधान, इसे एक सरणी में परिवर्तित करें, फ़िल्टर फ़ंक्शन का उपयोग करें और इसे वापस किसी ऑब्जेक्ट में परिवर्तित करें। फंक्शन करना भी होगा आसान ...

Btw। इसके साथ .length > 0मैं जांचता हूं कि क्या कोई खाली स्ट्रिंग / सरणी है, इसलिए यह खाली कुंजी को हटा देगा।

const MY_OBJECT = { f: 'te', a: [] }

Object.keys(MY_OBJECT)
 .filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
 .reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});

JS BIN https://jsbin.com/kugoyinora/edit?js,console


1
अच्छा कार्यात्मक समाधान
puiu

यह मुझे पंसद है! लेकिन मुझे लगता है कि सभी को हटाने के लिए nullऔर undefinedयह सिर्फ उपयोग करने के लिए सरल होगा MY_OBJECT[f] != null। आपका वर्तमान समाधान सबकुछ हटा देता है, लेकिन गैर-रिक्त तार / सूचियों को निकालता है और जब मान होते हैं तो एक त्रुटि फेंकता हैnull
रोटारेटी

ठीक है, तुम भी / श्रृंखला एकाधिक का उपयोग कर सकते हैं filter, अधिक पठनीय होगा।
माइकल जे। Zoidl

यदि आप इसे थोड़ा सामान्य करते हैं, तो मुझे लगता है कि आप लोडश के पास क्या omitकरते हैं, आपको कॉल करने से पहले obj की जांच करने की आवश्यकता है Object.keys:const omit = (obj, filter) => obj && Object.keys(obj).filter(key => !filter(obj[key])).reduce((acc,key) => {acc[key] = obj[key]; return acc}, {});
icc97

अच्छा है, लेकिन इस दृष्टिकोण के साथ किसी भी पूर्णांक मान को हटा दिया जाएगा।
घीस

5

आप json.stringify की प्रतिकृति तर्क का उपयोग करके एक पंक्ति में एक पुनरावर्ती निष्कासन कर सकते हैं

const removeNullValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)

उपयोग:

removeNullValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}

जैसा कि इमैनुएल की टिप्पणी में उल्लेख किया गया है, इस तकनीक ने केवल तभी काम किया है जब आपकी डेटा संरचना में केवल डेटा प्रकार होते हैं जिन्हें JSON प्रारूप (स्ट्रिंग्स, संख्या, सूची, आदि) में डाला जा सकता है।

(यह उत्तर नए Nullish Coalescing संचालक का उपयोग करने के लिए अद्यतन किया गया है । ब्राउज़र समर्थन के आधार पर आप इसके बजाय इसका उपयोग करना चाह सकते हैं (k,v) => v!=null ? v : undefined) :


1
इस तार, धर्मान्तरित करने के लिए दिनांक वस्तुओं में परिवर्तित कर देंगे NaNकरने के लिए nullजो नहीं हटाया जाता।
इमैनुएल एनके

4

यदि आप एक शुद्ध ES7 समाधान की 4 लाइनें चाहते हैं:

const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
  if (typeof v === 'boolean' || v) o[k] = clean(v);
  return o;
}, e instanceof Array ? [] : {}) : e;

या यदि आप अधिक पठनीय संस्करण पसंद करते हैं:

function filterEmpty(obj, [key, val]) {
  if (typeof val === 'boolean' || val) {
    obj[key] = clean(val)
  };

  return obj;
}

function clean(entry) {
  if (entry instanceof Object) {
    const type = entry instanceof Array ? [] : {};
    const entries = Object.entries(entry);

    return entries.reduce(filterEmpty, type);
  }

  return entry;
}

यह बूलियन मूल्यों को संरक्षित करेगा और यह सरणियों को भी साफ करेगा। यह एक साफ प्रतिलिपि को वापस करके मूल वस्तु को भी संरक्षित करता है।


4

मेरे पास अपनी परियोजना में एक ही परिदृश्य है और निम्नलिखित विधि का उपयोग करके हासिल किया है।

यह सभी डेटा प्रकारों के साथ काम करता है, ऊपर वर्णित कुछ तारीख और खाली सरणियों के साथ काम नहीं करता है।

removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) {
   Object.keys(obj).forEach(key => {
  if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
    delete obj[key];
  } else if (obj[key] && typeof obj[key] === 'object') {
    this.removeEmptyKeysFromObject(obj[key]);
  } else if (obj[key] == null || obj[key] === '') {
    delete obj[key];
  }

  if (obj[key]
    && typeof obj[key] === 'object'
    && Object.keys(obj[key]).length === 0
    && Object.prototype.toString.call(obj[key]) !== '[object Date]') {
    delete obj[key];
  }
});
  return obj;
}

इस फ़ंक्शन को किसी भी ऑब्जेक्ट को हटा देंEmptyKeysFromObject ()


4

एक गहरी खोज के लिए मैंने निम्नलिखित कोड का उपयोग किया है, हो सकता है कि यह इस प्रश्न को देखने वाले किसी के लिए भी उपयोगी होगा (यह चक्रीय निर्भरता के लिए उपयोग करने योग्य नहीं है):

function removeEmptyValues(obj) {
        for (var propName in obj) {
            if (!obj[propName] || obj[propName].length === 0) {
                delete obj[propName];
            } else if (typeof obj[propName] === 'object') {
                removeEmptyValues(obj[propName]);
            }
        }
        return obj;
    }

3

यदि आप जगह नहीं बदलना चाहते हैं, लेकिन हटाए गए अशक्त / अपरिभाषित के साथ एक क्लोन लौटा सकते हैं, तो आप ES6 कम फ़ंक्शन का उपयोग कर सकते हैं।

// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
  // Protect against null/undefined object passed in
  return Object.keys(obj || {}).reduce((x, k) => {
    // Check for null or undefined
    if (obj[k] != null) {
      x[k] = obj[k];
    }
    return x;
  }, {});
}

3

संपत्ति को हटाने के बजाय, आप उन कुंजियों के साथ एक नई वस्तु भी बना सकते हैं जो शून्य नहीं हैं।

const removeEmpty = (obj) => {
  return Object.keys(obj).filter(key => obj[key]).reduce(
    (newObj, key) => {
      newObj[key] = obj[key]
      return newObj
    }, {}
  )
}

3

इस समस्या को हल करने के तरीके पर बेन के जवाब पर पिगपैक करने के लिए _.pickBy, आप बहन पुस्तकालय में इस समस्या को हल कर सकते हैं: Underscore.js 's _.pick

var obj = {name: 'John', age: null};

var compacted = _.pick(obj, function(value) {
  return value !== null && value !== undefined;
});

देखें: JSFiddle उदाहरण


1
यह खाली सरणी देता है, आपने ऑब्जेक्ट में ऑब्जेक्ट का नाम भी बदल दिया है
स्टीफन ड्यूमॉन्ट

धन्यवाद स्टीफन! अभी के बारे में कैसे? मैंने JSFiddle लिंक को शामिल करने के लिए अपना जवाब अपडेट कर दिया है।
एलेक्स जॉनसन

_.omit (obj, _.isEmpty) का उपयोग करने का प्रयास करें; यह अधिक वैचारिक रूप से शुद्ध है और इसमें खाली स्ट्रिंग शामिल होगी।
स्टीफन डुमोंट

3

एक कम सहायक चाल कर सकता है (टाइप जाँच के बिना) -

const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

2

अगर किसी undefinedको गहरी खोज के साथ किसी ऑब्जेक्ट से मान हटाने की आवश्यकता है lodashतो यहां वह कोड है जो मैं उपयोग कर रहा हूं। सभी खाली मूल्यों ( null/ undefined) को निकालने के लिए इसे संशोधित करना काफी सरल है ।

function omitUndefinedDeep(obj) {
  return _.reduce(obj, function(result, value, key) {
    if (_.isObject(value)) {
      result[key] = omitUndefinedDeep(value);
    }
    else if (!_.isUndefined(value)) {
      result[key] = value;
    }
    return result;
  }, {});
}


1

यदि आप एसेलिंट का उपयोग करते हैं और नो-परम-रीसाइन शासन को ट्रिप करने से बचना चाहते हैं, तो आप ऑब्जेक्ट के साथ संयोजन का उपयोग कर सकते हैं। एक बहुत सुंदर ईएस 6 समाधान के लिए .reduce और एक कंप्यूटेड प्रॉपर्टी के नाम के साथ संयोजन में।

const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams) 
  .filter(key => queryParams[key] != null)
  .reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }

1

यहाँ nullsकेवल वस्तु का उपयोग किए बिना ES6 का उपयोग करके वस्तु से निकालने का एक कार्यात्मक तरीका है reduce:

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}

ट्रोल टिप्पणी इस बारे में दो बातें एक कार्यात्मक पैटर्न हैं: stripNullsफ़ंक्शन के भीतर यह संचायक फ़ंक्शन के दायरे के बाहर से एक संदर्भ का उपयोग करता है; और यह संचायक फ़ंक्शन के भीतर फ़िल्टर करके चिंताओं को भी मिलाता है। Yes (उदाहरण के लिए Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});) हां, यह दो बार फिल्टर्ड आइटम पर लूप करेगा, लेकिन वास्तविक पूर्ण नुकसान नगण्य है।
जेसन कस्ट

1

तुम भी उपयोग कर सकते हैं ...का उपयोग कर फैल वाक्य रचना forEachकुछ इस तरह:

let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};

Object.keys(obj).forEach(val => {
  const newVal = obj[val];
  cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});

console.info(cleanObj);

1

जगह में साफ वस्तु

// General cleanObj function
const cleanObj = (valsToRemoveArr, obj) => {
   Object.keys(obj).forEach( (key) =>
      if (valsToRemoveArr.includes(obj[key])){
         delete obj[key]
      }
   })
}

cleanObj([undefined, null], obj)

शुद्ध कार्य

const getObjWithoutVals = (dontReturnValsArr, obj) => {
    const cleanObj = {}
    Object.entries(obj).forEach( ([key, val]) => {
        if(!dontReturnValsArr.includes(val)){
            cleanObj[key]= val
        } 
    })
    return cleanObj
}

//To get a new object without `null` or `undefined` run: 
const nonEmptyObj = getObjWithoutVals([undefined, null], obj)

यह एक अच्छा, संभवतः एक-लाइनर, समाधान है
rekam

1

किसी वस्तु से रिक्त विशेषताओं को हटाने के लिए हम JSON.stringify और JSON.parse का उपयोग कर सकते हैं।

jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
               if (value == null || value == '' || value == [] || value == {})
                   return undefined;
               return value;
           });

यह ट्रिक वास्तव में मान्य है, जब तक आप यह सुनिश्चित करते हैं कि ओबीजी JSON-serializable है। और यह गहराई से भी काम करता है।
पोलाव

अमान्य सरणी और ऑब्जेक्ट तुलना ( {} != {}और [] != []), लेकिन अन्यथा दृष्टिकोण मान्य है
ऐवरस

1

यहां एक व्यापक पुनरावर्ती कार्य (मूल रूप से @chickens द्वारा एक पर आधारित) है जो होगा:

  • जो आप इसे बताते हैं उसे पुन: हटा दें defaults=[undefined, null, '', NaN]
  • नियमित रूप से वस्तुओं, सरणियों और दिनांक वस्तुओं को सही ढंग से संभालें
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}

उपयोग:

// based off the recursive cleanEmpty function by @chickens. 
// This one can also handle Date objects correctly 
// and has a defaults list for values you want stripped.

const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}


// testing

console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: new Date(),
      c: ''
    }]
  },
  g: NaN,
  h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: '',
      c: new Date()
    }]
  },
  g: [0, 1, 2, 3, 4],
  h: '',
}, [undefined, null]))


0

यदि आप शुद्ध / कार्यात्मक दृष्टिकोण पसंद करते हैं

const stripUndef = obj => 
  Object.keys(obj)
   .reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.