JavaScriptのオブジェクトから空白の属性を削除する


266

JavaScriptオブジェクト内undefinedまたはnullJavaScriptオブジェクト内のすべての属性を削除するにはどうすればよいですか?

(質問に似ている、この1アレイ用)


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

nullと未定義の注意点:

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"変数は外部スコープにリークします。
Eric Nguyen

4
(test [i] === null || test [i] === undefined)を(test [i] == null)に簡略化できます
jaf0

こんにちは、@EricNguyen。Cや他のいくつかの言語とは異なり、javascriptには変数のブロックスコープがありませ(関数スコープのみ)。したがって、変数iは常にforブロックの後にスコープにリークします。
ヘラルドリマ2016年

1
@GerardoLima、はい。これはすべて関数にラップされると思い込んでいました。私は(これはすべての機能に包まれていると仮定して)意味することは、VAR宣言を必要とするか、ということである私がしても外部の関数スコープのリークが発生します。
Eric Nguyen

これは、プリミティブオブジェクトのプロトタイプもループします。これはほとんどの場合望ましくありません。stackoverflow.com/a/2869372/1612318
Rotareti

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

4b)これは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の回答に基づく4b)への機能的アプローチ。これも新しいオブジェクトを返します: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]
})

5b) 再帰を使用し、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のでok明白です。しかし、それは好みの問題だと思います。
Rotareti 16

3
ES5フレーバーを備えた最初のバージョン:Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
神経伝達物質2017年

1
1行、機能なし:Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})
Paul Slm 2017年

7
私たちは徹底しようとしているので、不変のソリューションを見るのはいいかもしれません。これらはソースオブジェクトを変更しており、オブジェクトが変更されているため実際には不要なオブジェクトを偽って返しています。初心者は返されたオブジェクトの値をキャプチャし、ソースオブジェクトも変更される理由を不思議に思います。
マイクマクリン2018年

2
5)配列では機能しません(Object.keysは要素のキーとして配列の位置番号を返します)。おそらく他の人がこの問題を持っていますが、5をテストするとき、私はこれを見つけた
Eelco

95

lodashまたはunderscore.jsを使用している場合、簡単な解決策を次に示します。

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

var compacted = _.pickBy(obj);

これは、lodash 4、pre lodash 4またはunderscore.jsでのみ機能します_.pick(obj, _.identity)


1
鮮やかさ!ありがとうございました!ちなみに、私にとって明白ではなかったのは、次のように使用できることです。foo()。then(_。pickBy); //空の結果を
除外する

29
オブジェクトに0や空の文字列などの偽の値が含まれている場合、これは望ましい結果にならないことに注意してください。その後_.omit(obj, _.isUndefined)は良いです。
JHH

5
@JHHは_.isUndefinedオミットヌルは、使用はしない_.omitBy(obj, _.isNil)の両方を省略するundefinednull
ルカシュWiktor第

@LukaszWiktor正解、質問は未定義またはnullを要求しました。
JHH

88

ES6 +の最短ワンライナー

すべてfalsy値をフィルタ(""0falsenullundefined

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

フィルターnullundefined値:

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)), {})

再帰的ソリューション:フィルターnullundefined

オブジェクトの場合:

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ソリューションは、空のオブジェクトを返します{}Dateオブジェクトのために
エマニュエルNK

ワンライナーのもう少し読みやすさはそれらを素晴らしいものにするでしょう!!
zardilior

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

forループの開始後、オブジェクトhasOwnPropertyを使用しているかどうかを確認する必要がありますif(test.hasOwnProperty(i)) { ... }
Augie Gardner

@AugieGardnerなぜこれをチェックしたいのか知りたいです-よろしければ説明してください。(継承されたプロパティのチェックを妨げませんか?)
Wumms

24

JSON.stringifyは未定義のキーを削除します。

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

これは、深いオブジェクトに対しては機能しませんでしたが、上記のWummの回答は機能しました。
Suman

1
あなたが必要な場合nullとして扱われることをundefinedより多くの情報のため、使用置換機能はこの回答を参照してください。stackoverflow.com/questions/286141/...
Hoomanアスカリ

これはnull値を削除しないことに注意してください。試してください:let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }次にconsole.log(removeUndefined(a))。質問とはundefinednull価値観に関するものでした。
Mayid

13

あなたはおそらくdeleteキーワードを探しています。

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

4
これは彼が上記で行っていることですが、これもオブジェクトで未定義のままです。
Josh Bedo 2014

10

nullおよびundefined値が除外されたオブジェクトを返す最も簡単なLodashソリューション。

_.omitBy(obj, _.isNil)


これは、これまでで最もクリーンなソリューションです。
Jee Mok、2018年

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

CodePenの例


6

使用RAMDA#pickByあなたがすべて削除されますnullundefinedそしてfalse値:

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

@manroeが指摘したように、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または他の偽の値も拒否されるため、OPの質問にはおそらくより良い選択です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] }) }), {});
Kevin K.

6

json.stringifyのreplacer引数を使用して、1行で再帰的な削除を行うことができます

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

使用法:

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

Emmanuelのコメントで述べたように、この手法は、データ構造にJSON形式に変換できるデータ型(文字列、数値、リストなど)のみが含まれている場合にのみ機能しました。

(この回答は、新しいNullish Coalescingオペレーターを使用するように更新されています。ブラウザーのサポートニーズによっては、代わりにこの関数を使用することもできます。(k,v) => v!=null ? v : undefined


1
これは、文字列、変換にDateオブジェクトを変換するNaNnull削除されていません。
Emmanuel NK

5

あなたは!条件で短くすることができます

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

使用法を覚えておいてください:コメントで@semicolorがアナウンスするように:値が空の文字列、falseまたは0の場合、プロパティも削除されます


11
これにより、値が空の文字列(falseまたは0)の場合にもプロパティが削除されます。
セミコロン2014年

3
これはまさに、JSONリクエストから不要なフィールドを削除するために探していたものです。ありがとう!
凍結された2014年

[null, undefined].includes(r[k])代わりに使用します!r[k]
selmansamet

5

より短いES6の純粋なソリューション、それを配列に変換し、フィルター関数を使用してオブジェクトに変換します。関数を作るのも簡単でしょう...

ところで これ.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
Rotareti

そうです、複数を使用/チェーンすることもできますがfilter、もっと読みやすくなります。
Michael J.Zoidl 2017年

これを一般化した場合、わずかに私はあなたが何loadashのに近づくと思いますomit、あなたがobjをチェックする必要性をするのかは、呼び出す前に存在しているObject.keysconst omit = (obj, filter) => obj && Object.keys(obj).filter(key => !filter(obj[key])).reduce((acc,key) => {acc[key] = obj[key]; return acc}, {});
icc97

いいですが、整数値はこのアプローチで削除されます。
Ghis

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

この関数にオブジェクトを渡しますremoveEmptyKeysFromObject()


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

所定の位置で変更したくないが、null /未定義が削除されたクローンを返す場合は、ES6のreduce関数を使用できます。

// 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

プロパティを削除する代わりに、nullでないキーで新しいオブジェクトを作成することもできます。

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

3

上piggypackするにはベンの答え lodashのを使用してこの問題を解決する方法について_.pickBy、あなたはまた、姉妹ライブラリにこの問題を解決することができますUnderscore.jsさん_.pick

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

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

参照:JSFiddleの例


1
これは空の配列を返します。また、objの名前をオブジェクトに変更しました
Stephen DuMont

スティーブン、ありがとう!今はどう?JSFiddleリンクを含めるように回答を更新しました。
アレックスジョンソン

_.omit(obj、_.isEmpty);を使用してみてください。これはより概念的に純粋で、空の文字列が含まれます。
Stephen DuMont 2017

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

eslintを使用していて、no-param-reassignルールの作動を回避したい場合は、Object.assignを.reduceおよび計算されたプロパティ名と共に使用して、かなりエレガントなES6ソリューションを作成できます。

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

以下は、nullsES6を使用してオブジェクトのみを削除する機能的な方法reduceです。

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

トロルのコメントこれが機能的なパターンであることに関する2つのこと:stripNulls関数内では、アキュムレータ関数のスコープ外からの参照を使用します。また、アキュムレータ関数内でフィルタリングすることにより、懸念事項を混合します。😝(例Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});はい、フィルターされたアイテムを2回ループしますが、実現されるパフォーマンスの損失は無視できます。
Jason Cust、2018

1

次のようなものを使用して、...spread構文を使用することもできます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 '09 / 09/26

1

JSON.stringifyとJSON.parseを使用して、オブジェクトから空の属性を削除できます。

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

ObjがJSONでシリアライズ可能であることを確認する限り、このトリックは実際に有効です。そして、それは同様に深く働きます。
Polv

配列とオブジェクトの比較({} != {}および[] != [])は無効ですが、それ以外の方法は有効です
Aivaras

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]))


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.