lodashを使用してオブジェクトから未定義値とnull値を削除する方法は?


172

私は次のようなJavaScriptオブジェクトを持っています:

var my_object = { a:undefined, b:2, c:4, d:undefined };

未定義のプロパティをすべて削除するにはどうすればよいですか?偽の属性はとどまるはずです。

回答:


195

すべての誤った値を削除する場合、最もコンパクトな方法は次のとおりです。

Lodash 4.xの以降

_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

以下のためのレガシー Lodash 3.xの:

_.pick(obj, _.identity);

_.pick({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

63
lodash 4では、これは次のようになることに注意してください_.pickBy(obj, _.identity);
Tom Spencer

30
このメソッドはfalse値も削除することに注意してください。
2017年

12
注意してください、これは持っブールプロパティを削除しますfalseVALUを
サイラム

6
falseを削除するだけでなく、値として0と ''を持つ属性も削除します...良い考えではありません。
フェデリコブダッシ

4
この答えは偽の値も削除するため、正しい答えではありません。以下の私の答えを確認してください。
ティアゴベルトロ

224

あなたは、単に連鎖できる_.omit()_.isUndefinedし、_.isNull組成物、および遅延評価で結果を取得します。

デモ

var result = _(my_object).omit(_.isUndefined).omit(_.isNull).value();

2016年3月14日更新

コメントセクションのダイラントで述べたように、_.omitBy()関数ではプロパティの代わりに述語を使用するため、関数を使用する必要があります。lodashバージョン以降ではこれを使用する必要が4.0.0あります。

デモ

var result = _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();

2016年6月1日更新

コメントとしてマックスTruxa、既に代替提供lodash _.isNil、両方のためのチェックnullとをundefined

var result = _.omitBy(my_object, _.isNil);

7
lodashのより新しいバージョンを使用しているユーザーは、のomitBy代わりに関数を使用する必要がありますomit。したがって、_(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
ダイラントは

31
lodash 4.0.0以降で_.isNilは、チェーン_.isUndefinedとの代わりに使用できます_.isNull。このことはさらに短くなります:var result = _.omitBy(my_object, _.isNil);
最大Truxa

@MaxTruxa「Nil」値を再帰的にチェックするように変更するにはどうすればよいですか?
16年

1
Lodash omitByはと比べてパフォーマンスが低いpickByため、後者を推奨し、iteratee関数の条件を逆にします。上記の受け入れられた答えはそれを正しくしました。
Ernesto

1
OPの質問はnullundefined値と値のみを指定しています。identity述語も削除されますfalseあなたは、単に質問の意図、私は私の答えに問題が表示されていない時に、それをベースそうならば、値を。さらに、「パフォーマンス」について取り組む場合は、デフォルトで、述部を否定してomitBy呼び出します。したがって、パフォーマンスの点では、それは小さすぎて重要ではありません。pickByidentity
ryeballar

38

lodashを使用_.compact(array)している場合は、を使用して、配列からすべての誤った値を削除できます。

_.compact([0, 1, false, 2, '', 3]);
// => [1, 2, 3]

https://lodash.com/docs/4.17.4#compact


36
コンパクトは配列に適用されますが、問題はオブジェクトに関するものです
guidoman

1
0を維持したい場合を除いて。
Sammi

2
@Sammi、_.pickBy(object, _.isNumber)その場合に使用できます。
John Rix

1
@Herick、ありがとうございます。うまくいきました。そろそろ寝ます。
テクノフィル2018

1
@technophyle、私はあなたに同意します(この回答を書いたのは私です)。しかし、私はこの答えをここに置いいます。少なくとも、いくつかの人々の問題を解決するからです。
JavaFish '19

24

正解は次のとおりです。

_.omitBy({ a: null, b: 1, c: undefined, d: false }, _.isNil)

その結果:

{b: 1, d: false}

他の人々によってここで与えられた代替案:

_.pickBy({ a: null, b: 1, c: undefined, d: false }, _.identity);

falseここでは不要な値も削除されます。


{"a":1,"b":{"a":1,"b":null,"c":undefined}}、object.bプロパティb、 'c'は削除されません
mqliutie

予想通り@mqliutie。
TiagoBértolo19年

17

ただ:

_.omit(my_object, _.isUndefined)

上記はnull、元の例には含まれておらず、件名のみで言及されているため、アカウントの値は考慮されていませんが、エレガントであり、その用途がある可能性があるため、そのままにしておきます。

以下は完全な例ですが、簡潔ではありませんが、より完全です。

var obj = { a: undefined, b: 2, c: 4, d: undefined, e: null, f: false, g: '', h: 0 };
console.log(_.omit(obj, function(v) { return _.isUndefined(v) || _.isNull(v); }));

7
これはLodash v.3用であることに注意してください。v.4の場合、を使用する必要があります_.omitBy
PhiLho

16

他の回答を完了するには、lodash 4で未定義とnullのみを無視する(そしてのようなプロパティは無視するfalse)場合は、述語を_.pickBy次のように使用できます。

_.pickBy(obj, v !== null && v !== undefined)

以下の例:

const obj = { a: undefined, b: 123, c: true, d: false, e: null};

const filteredObject = _.pickBy(obj, v => v !== null && v !== undefined);

console.log = (obj) => document.write(JSON.stringify(filteredObject, null, 2));
console.log(filteredObject);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>


1
削除したくない場合、これが最善の解決策である0''false値を。また、コールバックをに短縮することもできますv => v != null
SimpleJ

2
シンプルなソリューション。これありがとう。
Arjun Gペランブラ2018

10

lodash docsによると:

_.compact(_.map(array, fn))

また、あなたはすべてのヌルを取り除くことができます


6

深くネストされたオブジェクトの場合、lodash> 4のスニペットを使用できます

const removeObjectsWithNull = (obj) => {
    return _(obj)
      .pickBy(_.isObject) // get only objects
      .mapValues(removeObjectsWithNull) // call only for values as objects
      .assign(_.omitBy(obj, _.isObject)) // save back result that is not object
      .omitBy(_.isNil) // remove null and undefined from object
      .value(); // get value
};

5

undefinedオブジェクトから(深く)削除することで同様の問題が発生し、プレーンな古いオブジェクトを変換してJSONを使用しても問題がない場合、すばやくダーティなヘルパー関数は次のようになります。

function stripUndefined(obj) {
  return JSON.parse(JSON.stringify(obj));
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description

「...未定義、関数、またはシンボルが変換中に検出された場合は、省略されるか(オブジェクトで検出された場合)、またはnullに打ち切られます(配列で検出された場合)。」


5

純粋なJavaScriptの場合:(Object.entriesはES7ですが、Object.assignはES6ですが、同等のES5がObject.keysを使用するだけでも実行可能です); v != nullnullと未定義の両方のチェックにも注意してください。

> var d = { a:undefined, b:2, c:0, d:undefined, e: null, f: 0.3, s: "", t: false };
undefined
> Object.entries(d)
    .filter(([ k, v ]) => (v != null))
    .reduce((acc, [k, v]) => Object.assign(acc, {[k]: v}), {})
{ b: 2, c: 0, f: 0.3, s: '', t: false }

編集:以下は、ES5 Object.keysのみのバージョンです。ただし、一般的に、Node v8のES7はかなり楽しいです;-)

> Object.keys(d)
    .filter(function(k) { return d[k] != null; })
    .reduce(function(acc, k) { acc[k] = d[k]; return acc; }, {});
{ b: 2, c: 0, f: 0.3, s: '', t: false }

2017年10月の更新:ノードv8(v8.3以降)では、オブジェクト拡散構成が追加されました。

> var d = { a:undefined, b:2, c:0, d:undefined,
    e: null, f: -0.0, s: "", t: false, inf: +Infinity, nan: NaN };
undefined
> Object.entries(d)
    .filter(([ k, v ]) => (v != null))
    .reduce((acc, [k, v]) => ({...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }

または1つの削減内のみ:

> Object.entries(d)
   .reduce((acc, [k, v]) => (v==null ? acc : {...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }

更新:誰かが再帰的に欲しいですか?それほど難しくもありません。isObjectの追加のチェックが必要で、再帰的にそれ自体を呼び出します。

> function isObject(o) {
    return Object.prototype.toString.call(o) === "[object Object]"; }
undefined
> function dropNullUndefined(d) {
    return Object.entries(d)
      .reduce((acc, [k, v]) => (
        v == null ? acc :
         {...acc, [k]: (isObject(v) ? dropNullUndefined(v) : v) }
      ), {});
  }
> dropNullUndefined({a: 3, b:null})
{ a: 3 }
> dropNullUndefined({a: 3, b:null, c: { d: 0, e: undefined }})
{ a: 3, c: { d: 0 } }

私の結論:純粋なJavascriptで実行できる場合は、サードパーティライブラリの依存関係を避けます。


Object.fromEntriesを使用して、reduceの使用を回避できます:Object.fromEntries(Object.entries(d).filter(([k、v])=>(v!= null)))
ppierre

5

一部のユーザーは、のみ を明確に削除することを目的とした質問に到達した可能性があるためundefined、次のように使用できます。

  • Lodashメソッドの組み合わせ

    _.omitBy(object, _.isUndefined)
  • rundef唯一の削除パッケージ、undefinedプロパティを

    rundef(object)

プロパティを再帰的に削除する必要がある場合undefinedは、rundefパッケージにもrecursiveオプションがあります。

rundef(object, false, true);

詳細については、ドキュメントを参照してください。


3

これが私がとるlodashのアプローチです:

_(my_object)
    .pairs()
    .reject(function(item) {
        return _.isUndefined(item[1]) ||
            _.isNull(item[1]);
    })
    .zipObject()
    .value()

対()関数は、キー/値の配列の配列に入力オブジェクトを回転させます。これを行うと、reject()を使用してundefinednull値を削除するのが簡単になります。その後、拒否されなかったペアが残り、これらはzipObject()への入力であり、オブジェクトを再構築します。


3

undefined == null次のように書くことができることを考慮に入れてください:

let collection = {
  a: undefined,
  b: 2,
  c: 4,
  d: null,
}

console.log(_.omit(collection, it => it == null))
// -> { b: 2, c: 4 }

JSBinの例


1
これを再訪します...なぜかわかりませんが、今回は_.omitByを使用する必要がありました... json = _.omitBy(json、(it)=> it == null);
danday74 2016年

2

pickByはデフォルトでIDを使用します。

_.pickBy({ a: null, b: 1, c: undefined, d: false });

@ Tx3の回答のこの短いバージョンが好きです。うまくいきます!
ジョーダン


1

ロダッシュ(またはアンダースコア)を使用すると

var my_object = { a:undefined, b:2, c:4, d:undefined, e:null };

var passedKeys = _.reject(Object.keys(my_object), function(key){ return _.isUndefined(my_object[key]) || _.isNull(my_object[key]) })

newObject = {};
_.each(passedKeys, function(key){
    newObject[key] = my_object[key];
});

それ以外の場合、バニラJavaScriptを使用すると、次のことができます

var my_object = { a:undefined, b:2, c:4, d:undefined };
var new_object = {};

Object.keys(my_object).forEach(function(key){
    if (typeof my_object[key] != 'undefined' && my_object[key]!=null){
        new_object[key] = my_object[key];
    }
});

「未定義」または「null」が拒否されるだけでなく、「false」、「0」、空の文字列、{}などの他の誤った値も含まれるため、誤ったテストを使用しないでください。したがって、単純かつ理解しやすくするために、上にコーディングした明示的な比較を使用することにしました。


1
ただし、これは再帰的ではありません
user3743222

1

すべて省略するfalseyの値をが、基本論理要素を保つこの解決に役立ちます。

_.omitBy(fields, v => (_.isBoolean(v)||_.isFinite(v)) ? false : _.isEmpty(v));

let fields = {
str: 'CAD',
numberStr: '123',
number  : 123,
boolStrT: 'true',
boolStrF: 'false',
boolFalse : false,
boolTrue  : true,
undef: undefined,
nul: null,
emptyStr: '',
array: [1,2,3],
emptyArr: []
};

let nobj = _.omitBy(fields, v => (_.isBoolean(v)||_.isFinite(v)) ? false : _.isEmpty(v));

console.log(nobj);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>


0
var my_object = { a:undefined, b:2, c:4, d:undefined };

var newObject = _.reject(my_collection, function(val){ return _.isUndefined(val) })

//--> newCollection = { b: 2, c: 4 }

1
_.rejectは、JSONではなく、入力を配列(キーではなく値のみを考慮する)として扱います。結果のnewObjectは[2,4]であり、{b:2、c:4}ではありません。さらに、「null」キーを拒否しません。
TaoPR、2015年

0

下線を使用して空の文字列も処理します。

var my_object = { a:undefined, b:2, c:4, d:undefined, k: null, p: false, s: '', z: 0 };

var result =_.omit(my_object, function(value) {
  return _.isUndefined(value) || _.isNull(value) || value === '';
});

console.log(result); //Object {b: 2, c: 4, p: false, z: 0}

jsbin


0

深くネストされたオブジェクトと配列の場合。文字列とNaNから空の値を除外する

function isBlank(value) {
  return _.isEmpty(value) && !_.isNumber(value) || _.isNaN(value);
}
var removeObjectsWithNull = (obj) => {
  return _(obj).pickBy(_.isObject)
    .mapValues(removeObjectsWithNull)
    .assign(_.omitBy(obj, _.isObject))
    .assign(_.omitBy(obj, _.isArray))
    .omitBy(_.isNil).omitBy(isBlank)
    .value();
}
var obj = {
  teste: undefined,
  nullV: null,
  x: 10,
  name: 'Maria Sophia Moura',
  a: null,
  b: '',
  c: {
    a: [{
      n: 'Gleidson',
      i: 248
    }, {
      t: 'Marta'
    }],
    g: 'Teste',
    eager: {
      p: 'Palavra'
    }
  }
}
removeObjectsWithNull(obj)

結果:

{
   "c": {
      "a": [
         {
            "n": "Gleidson",
            "i": 248
         },
         {
            "t": "Marta"
         }
      ],
      "g": "Teste",
      "eager": {
         "p": "Palavra"
      }
   },
   "x": 10,
   "name": "Maria Sophia Moura"
}


0

オブジェクトの配列から削除するためにここに来て、lodashを使用する人は、次のようなことができます:


 const objects = [{ a: 'string', b: false, c: 'string', d: undefined }]
 const result = objects.map(({ a, b, c, d }) => _.pickBy({ a,b,c,d }, _.identity))

 // [{ a: 'string', c: 'string' }]

注:破壊したくない場合は破壊する必要はありません。

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