简体   繁体   English

如何使用 lodash 从对象中删除未定义和空值?

[英]How to remove undefined and null values from an object using lodash?

I have a Javascript object like:我有一个 Javascript 对象,例如:

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

How to remove all the undefined properties?如何删除所有未定义的属性? False attributes should stay.虚假属性应该保留。

You can simply chain _.omit() with _.isUndefined and _.isNull compositions, and get the result with lazy evaluation.您可以简单地将_.omit()_.isUndefined_.isNull组合链接起来,并通过延迟评估获得结果。

Demo 演示

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

Update March 14, 2016 : 2016 年 3 月 14 日更新

As mentioned by dylants in the comment section, you should use the _.omitBy() function since it uses a predicate instead of a property.正如dyants在评论部分提到的,您应该使用_.omitBy()函数,因为它使用谓词而不是属性。 You should use this for lodash version 4.0.0 and above.你应该在 lodash 4.0.0及更高版本中使用它。

DEMO 演示

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

Update June 1, 2016 : 2016 年 6 月 1 日更新

As commented by Max Truxa , lodash already provided an alternative _.isNil , which checks for both null and undefined :正如Max Truxa所评论的,lodash 已经提供了一个替代_.isNil ,它检查nullundefined

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

If you want to remove all falsey values then the most compact way is:如果要删除所有falsey值,那么最紧凑的方法是:

For Lodash 4.x and later :对于Lodash 4.x 及更高版本

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

For legacy Lodash 3.x:对于旧版Lodash 3.x:

_.pick(obj, _.identity);

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

The correct answer is:正确答案是:

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

That results in:这导致:

{b: 1, d: false}

The alternative given here by other people:其他人在这里给出的替代方案:

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

Will remove also false values which is not desired here.还将删除此处不需要的false值。

if you are using lodash, you can use _.compact(array) to remove all falsely values from an array.如果您使用 lodash,则可以使用_.compact(array)从数组中删除所有错误值。

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

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

To complete the other answers, in lodash 4 to ignore only undefined and null (And not properties like false ) you can use a predicate in _.pickBy :要完成其他答案,在 lodash 4 中只忽略 undefined 和 null (而不是像false这样的属性),您可以在_.pickBy使用谓词:

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

Example below :下面的例子:

 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>

Just:只是:

_.omit(my_object, _.isUndefined)

The above doesn't take in account null values, as they are missing from the original example and mentioned only in the subject, but I leave it as it is elegant and might have its uses.上面没有考虑null值,因为它们在原始示例中缺失并且仅在主题中提到,但我保留它,因为它很优雅并且可能有它的用途。

Here is the complete example, less concise, but more complete.这是完整的示例,不那么简洁,但更完整。

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

According to lodash docs:根据 lodash 文档:

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

Also you can filter out all nulls您也可以过滤掉所有空值

For deep nested object you can use my snippet for lodash > 4对于深层嵌套对象,您可以使用我的 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
};

I encountered a similar problem with removing undefined from an object (deeply), and found that if you are OK to convert your plain old object and use JSON, a quick and dirty helper function would look like this:我在从对象中删除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 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description

"...If undefined, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array)." “...如果在转换过程中遇到未定义的函数或符号,则将其省略(在对象中找到时)或删失为 null(在数组中找到时)。”

with pure JavaScript: (although Object.entries is ES7, Object.assign is ES6; but equivalent ES5 uses Object.keys only should be also doable);使用纯 JavaScript:(虽然 Object.entries 是 ES7,Object.assign 是 ES6;但等效的 ES5 只使用 Object.keys 应该也是可行的); also notice v != null checks for both null and undefined;还要注意v != null检查 null 和 undefined ;

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

Edit: this below is the version with ES5 Object.keys only: but generally with ES7 in Node v8 is pretty much enjoyable ;-)编辑:以下是仅包含 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 }

Update in October 2017 : with Node v8 (since v8.3 or so) now it has object spreading construct: 2017 年 10 月更新:使用 Node 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 }

or within one reduce only:或仅在一次减少:

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

Update: someone want recursive?更新:有人想要递归? isn't that hard either, just need an additional check of isObject, and recursively call itself:也不是那么难,只需要额外检查 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 } }

my conclusion: if pure Javascript can do, I would avoid any third party library dependencies:我的结论:如果纯 Javascript 可以做到,我会避免任何第三方库依赖项:

Since some of you might have arrived at the question looking to specifically removing only undefined , you can use:由于有些人可能在寻求专门去除,唯一的问题已经到了undefined ,你可以使用:

  • a combination of Lodash methods Lodash 方法的组合

    _.omitBy(object, _.isUndefined)
  • the rundef package, which removes only undefined properties rundef包,它只删除undefined属性

    rundef(object)

If you need to recursively remove undefined properties, the rundef package also has a recursive option.如果需要递归删除undefined属性, rundef包也有recursive选项。

rundef(object, false, true);

See the documentation for more details.有关更多详细信息,请参阅文档

Here's the lodash approach I'd take:这是我采用的 lodash 方法:

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

The pairs() function turns the input object into an array of key/value arrays. pair()函数将输入对象转换为键/值数组的数组。 You do this so that it's easier to use reject() to eliminate undefined and null values.这样做是为了更容易使用reject()来消除undefinednull值。 After, you're left with pairs that weren't rejected, and these are input for zipObject() , which reconstructs your object for you.之后,您会得到未被拒绝的对,这些是zipObject() 的输入,它为您重建您的对象。

Taking in account that undefined == null we can write as follows:考虑到undefined == null我们可以这样写:

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

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

JSBin example JSB 示例

pickBy默认使用身份

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

I like using _.pickBy, because you have full control over what you are removing:我喜欢使用 _.pickBy,因为您可以完全控制要删除的内容:

var person = {"name":"bill","age":21,"sex":undefined,"height":null};

var cleanPerson = _.pickBy(person, function(value, key) {
  return !(value === undefined || value === null);
});

Source: https://www.codegrepper.com/?search_term=lodash+remove+undefined+values+from+object来源: https : //www.codegrepper.com/?search_term=lodash+remove+undefined+values+from+object

最短的方式(lodash v4):

_.pickBy(my_object)

从对象中删除未定义、空和空字符串

_.omitBy(object, (v) => _.isUndefined(v) || _.isNull(v) || v === '');

With lodash (or underscore) You may do使用 lodash(或下划线)你可以

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

Otherwise, with vanilla JavaScript, you can do否则,使用 vanilla 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];
    }
});

Not to use a falsey test, because not only "undefined" or "null" will be rejected , also is other falsey value like "false", "0", empty string, {}.不要使用虚假测试,因为不仅“未定义”或“空”会被拒绝,其他虚假值如“假”、“0”、空字符串、{}也会被拒绝 Thus, just to make it simple and understandable, I opted to use explicit comparison as coded above.因此,为了简单易懂,我选择使用上面编码的显式比较。

To omit all falsey values but keep the boolean primitives this solution helps.要省略所有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>

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 }

I would use underscore and take care of empty strings too:我会使用下划线并处理空字符串:

 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 . jsbin

For deep nested object and arrays.对于深度嵌套的对象和数组。 and exclude empty values from string and NaN并从字符串和 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)

result:结果:

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

For those of you getting here looking to remove from an array of objects and using lodash you can do something like this:对于那些想要从对象数组中删除并使用 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' }]

Note: You don't have to destruct if you don't want to.注意:如果你不想,你不必破坏。

If you don't want to remove false values.如果您不想删除false值。 Here is an example:下面是一个例子:

obj = {
  "a": null,
  "c": undefined,
  "d": "a",
  "e": false,
  "f": true
}
_.pickBy(obj, x => x === false || x)
> {
    "d": "a",
    "e": false,
    "f": true
  }

You can also use Object.entries with Array.prototype.filter .您还可以将Object.entriesArray.prototype.filter一起使用。

const omitNullish = (object) => 
   Object.fromEntries(
       Object.entries(object).filter(([, value]) => value != null)
   )

omitNullish({ a: null, b: 1, c: undefined, d: false, e: 0 }) // { b: 1, d: false, e: 0}

If you want to use lodash, they are removing omit from v5 so an alternative is to use fp/pickBy along with isNil and negate .如果你想使用 lodash,他们会从 v5 中删除 omit,所以另一种选择是使用fp/pickBy以及isNilnegate

import pickBy from 'lodash/fp/pickBy'
import isNil from 'lodash/isNil';
import negate from 'lodash/negate';


const omitNullish = pickBy(negate(isNil))

omitNullish({ a: null, b: 1, c: undefined, d: false, e: 0 }) // { b: 1, d: false, e: 0}

I was able to do this in deep objects that include arrays with just one lodash function, transform .我能够在包含只有一个 lodash 函数transform的数组的深层对象中做到这一点。

Note that the double-unequal (!= null) is intentional as it will also match undefined, as is the typeof 'object' check as it will match both object and array.请注意,双重不等(!= null)是有意的,因为它也将匹配未定义,就像 typeof 'object' 检查一样,因为它将匹配对象和数组。

This is for use with plain data objects only that don't contain classes.这仅用于不包含类的纯数据对象。

const cloneDeepSanitized = (obj) =>
  Array.isArray(obj)
    ? obj.filter((entry) => entry != null).map(cloneDeepSanitized)
    : transform(
        obj,
        (result, val, key) => {
          if (val != null) {
            result[key] =
              typeof val === 'object' ? cloneDeepSanitized(val) : val;
          }
        },
        {},
      );

You can use lodash to remove null and undefined objects , but you should konw what lodash method you need to use, many dev uses isNil to remove the Null and undefined objects , but this function not remove the empty objects (' ')您可以使用 lodash 删除空对象和未定义对象,但您应该知道需要使用什么 lodash 方法,许多开发人员使用 isNil 删除空对象和未定义对象,但此函数不会删除空对象('')

you can use isEmpty to remove Null , Undefined and您可以使用 isEmpty 删除 Null 、 Undefined 和

import pickBy from 'lodash/fp/pickBy'
import negate from 'lodash/negate';
import isEmpty from 'lodash/isEmpty';

const omitNullish = pickBy(negate(isEmpty));

      addressObject = {
      "a": null,
      "c": undefined,
      "d": "",
      "e": "test1",
      "f": "test2
    }

 const notNullObjects = omitNullish(addressObject);
 
 console.log(notNullObjects); 

you will have this object : { "e": "test1", "f": "test2 }你将拥有这个对象:{ "e": "test1", "f": "test2 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM