Làm thế nào để loại bỏ các giá trị không xác định và null khỏi một đối tượng bằng cách sử dụng lodash?


172

Tôi có một đối tượng Javascript như:

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

Làm thế nào để loại bỏ tất cả các thuộc tính không xác định? Thuộc tính sai nên ở lại.

Câu trả lời:


195

Nếu bạn muốn xóa tất cả các giá trị falsey thì cách nhỏ gọn nhất là:

Đối với Lodash 4.x trở lên :

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

Đối với di sản Lodash 3.x:

_.pick(obj, _.identity);

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

63
Xin lưu ý rằng trong lodash 4, điều này nên là_.pickBy(obj, _.identity);
Tom Spencer

30
Plaese lưu ý phương pháp này cũng sẽ loại bỏ giá trị sai.
không giới hạn

12
Hãy cẩn thận, điều này sẽ loại bỏ boolean tài sản có falsevalu
Sài Ram

6
Bên cạnh việc xóa false, nó cũng sẽ xóa các thuộc tính có giá trị 0 và '' dưới dạng giá trị ... không phải là một ý tưởng hay.
Federico Budassi

4
Câu trả lời này không đúng vì nó cũng loại bỏ các giá trị giả. Kiểm tra câu trả lời của tôi dưới đây.
Tiago Bértolo 15/03/19

224

Bạn có thể chỉ cần xâu chuỗi _.omit()với _.isUndefinedvà các _.isNulltác phẩm, và nhận được kết quả với đánh giá lười biếng.

Bản giới thiệu

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

Cập nhật ngày 14 tháng 3 năm 2016 :

Như được đề cập bởi các dylants trong phần bình luận, bạn nên sử dụng _.omitBy()hàm vì nó sử dụng một vị ngữ thay vì một thuộc tính. Bạn nên sử dụng điều này cho phiên bản lodash 4.0.0trở lên.

BẢN GIỚI THIỆU

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

Cập nhật ngày 1 tháng 6 năm 2016 :

Theo nhận xét của Max Truxa , lodash đã cung cấp một giải pháp thay thế _.isNil, kiểm tra cả hai nullundefined:

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

7
Những người đang sử dụng các phiên bản mới hơn của lodash nên sử dụng omitBychức năng thay vì omit. Vì vậy_(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
việc

31
Kể từ lodash 4.0.0, bạn có thể sử dụng _.isNilthay vì xích _.isUndefined_.isNull. Điều này làm cho nó thậm chí còn ngắn hơn:var result = _.omitBy(my_object, _.isNil);
Max Truxa

@MaxTruxa bạn sẽ sửa đổi nó như thế nào để kiểm tra các giá trị "Nil" theo cách đệ quy?
báo vào

1
Lodash omitBylà ít hiệu suất hơn pickBy, vì vậy nên ưu tiên thứ hai và điều kiện trong hàm iteratee đảo ngược. Câu trả lời được chấp nhận ở trên đã đúng.
Ernesto

1
Câu hỏi của OP chỉ được chỉ định nullundefinedgiá trị. Vị identityngữ cũng sẽ loại bỏ falsecác giá trị, vì vậy nếu bạn chỉ đơn giản dựa trên ý định của câu hỏi thì tôi không thấy vấn đề gì với câu trả lời của mình. Ngoài ra, nếu chúng ta đang nói về "hiệu suất" , theo mặc định , omitBychỉ cần gọi pickByvới một identityvị từ phủ định. Vì vậy, về mặt hiệu suất, nó quá nhỏ không đáng kể.
ryeballar

38

nếu bạn đang sử dụng lodash, bạn có thể sử dụng _.compact(array)để xóa tất cả các giá trị sai lệch khỏi một mảng.

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

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


36
nhỏ gọn áp dụng cho mảng nhưng câu hỏi là về các đối tượng
hướng dẫn

1
Ngoại trừ tôi muốn giữ 0. Argh, thật gần.
Sammi

2
@Sammi, bạn có thể sử dụng _.pickBy(object, _.isNumber)trong trường hợp đó.
John Rix

1
Cảm ơn bạn @Herick. Điều đó làm việc. Tôi sẽ đi ngủ bây giờ
Technophyle

1
@technophyle, tôi đồng ý với bạn (và tôi là người đã viết câu trả lời này, ha). Nhưng tôi đang giữ câu trả lời này ở đây bởi vì, ít nhất, nó giải quyết được một số vấn đề của mọi người.
JavaFish

24

Đáp án đúng là:

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

Điều đó dẫn đến:

{b: 1, d: false}

Người khác thay thế ở đây:

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

Cũng sẽ loại bỏ falsecác giá trị không mong muốn ở đây.


{"a":1,"b":{"a":1,"b":null,"c":undefined}}, thuộc tính object.b b, 'c' sẽ không bị xóa
mqliutie

@mqliutie như mong đợi.
Tiago Bértolo

17

Chỉ:

_.omit(my_object, _.isUndefined)

Ở trên không có tài khoản null giá trị , vì chúng bị thiếu trong ví dụ ban đầu và chỉ được đề cập trong chủ đề, nhưng tôi để nó vì nó thanh lịch và có thể có công dụng của nó.

Dưới đây là ví dụ đầy đủ, ít súc tích, nhưng đầy đủ hơn.

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
Lưu ý rằng đây là cho Lodash v.3. Đối với v.4, bạn phải sử dụng _.omitBy.
PhiLho

16

Để hoàn thành các câu trả lời khác, trong lodash 4 chỉ bỏ qua không xác định và null (Và không thuộc tính như false), bạn có thể sử dụng một vị ngữ trong _.pickBy:

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

Ví dụ dưới đây:

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
Đây là giải pháp tốt nhất nếu bạn không muốn loại bỏ 0, '', falsegiá trị. Ngoài ra, bạn có thể rút ngắn cuộc gọi lại v => v != null.
SimpleJ

2
Giải pháp đơn giản. Cảm ơn vì điều này.
Arjun G Perambra

10

Theo tài liệu lodash:

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

Ngoài ra, bạn có thể lọc ra tất cả null


6

Đối với đối tượng lồng nhau sâu, bạn có thể sử dụng đoạn mã của tôi cho 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

Tôi đã gặp một vấn đề tương tự với việc xóa undefinedkhỏi một đối tượng (sâu) và thấy rằng nếu bạn đồng ý chuyển đổi đối tượng cũ đơn giản của mình và sử dụng JSON, một hàm trợ giúp nhanh và bẩn sẽ như thế này:

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

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

"... Nếu không được xác định, một hàm hoặc ký hiệu gặp phải trong quá trình chuyển đổi, nó sẽ bị bỏ qua (khi nó được tìm thấy trong một đối tượng) hoặc bị kiểm duyệt thành null (khi nó được tìm thấy trong một mảng)."


5

với JavaScript thuần túy: (mặc dù Object.entries là ES7, Object.assign là ES6; nhưng ES5 tương đương chỉ sử dụng Object.keys cũng có thể thực hiện được); cũng thông báo v != nullkiểm tra cho cả null và không xác định;

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

Chỉnh sửa: đây là phiên bản chỉ có ES5 Object.keys: nhưng nói chung với ES7 trong Node v8 khá thú vị ;-)

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

Cập nhật vào tháng 10 năm 2017 : với Node v8 (kể từ v8.3 trở lên) bây giờ nó có cấu trúc trải rộng đối tượng:

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

hoặc chỉ trong một lần giảm:

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

Cập nhật: ai đó muốn đệ quy? cũng không khó lắm, chỉ cần kiểm tra bổ sung isObject và tự gọi đệ quy:

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

kết luận của tôi: nếu Javascript thuần túy có thể làm được, tôi sẽ tránh mọi phụ thuộc thư viện của bên thứ ba:


5

Vì một số bạn có thể đã đến lúc các câu hỏi tìm kiếm cụ thể tháo chỉ undefined , bạn có thể sử dụng:

  • sự kết hợp của các phương pháp Lodash

    _.omitBy(object, _.isUndefined)
  • các rundefgói, trong đó loại bỏ chỉ undefinedtính

    rundef(object)

Nếu bạn cần loại bỏ đệ quy các undefinedthuộc tính, rundefgói cũng có một recursivetùy chọn.

rundef(object, false, true);

Xem tài liệu để biết thêm chi tiết.


3

Đây là cách tiếp cận lodash tôi sẽ thực hiện:

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

Hàm cặp () biến đối tượng đầu vào thành một mảng các mảng khóa / giá trị. Bạn làm điều này để dễ sử dụng từ chối () để loại bỏ undefinednullcác giá trị. Sau đó, bạn còn lại các cặp không bị từ chối và đây là các đầu vào cho zipObject () , cấu trúc lại đối tượng của bạn cho bạn.


3

Có tài khoản mà undefined == nullchúng ta có thể viết như sau:

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

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

Ví dụ về JSBin


1
xem lại điều này ... không chắc tại sao nhưng lần này tôi phải sử dụng _.omitBy ... json = _.omitBy (json, (it) => it == null);
danday74

2

PickBy sử dụng danh tính theo mặc định:

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

Tôi thích phiên bản ngắn hơn của câu trả lời của @ Tx3. Hoạt động độc đáo!
Jordan


1

Với lodash (hoặc gạch dưới) Bạn có thể làm

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

Nếu không, với JavaScript vanilla, bạn có thể làm

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

Không sử dụng thử nghiệm falsey, bởi vì không chỉ "không xác định" hoặc "null" sẽ bị từ chối , mà còn là giá trị falsey khác như "false", "0", chuỗi rỗng, {}. Vì vậy, để làm cho nó đơn giản và dễ hiểu, tôi đã chọn sử dụng so sánh rõ ràng như được mã hóa ở trên.


1
mặc dù điều này không phải là đệ quy
dùng3743222

1

Để bỏ qua tất cả các giá trị falsey nhưng giữ nguyên các boolean, giải pháp này giúp.

_.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 coi đầu vào là mảng (nó chỉ chiếm các giá trị, không phải các khóa), không phải là JSON. NewObject kết quả là [2,4] không {b: 2, c: 4}. Hơn nữa, nó không từ chối khóa "null".
TaoPR

0

Tôi sẽ sử dụng dấu gạch dưới và cũng quan tâm đến các chuỗi trống:

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

Đối với các đối tượng lồng sâu và mảng. và loại trừ các giá trị trống từ chuỗi và 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)

kết quả:

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


0

Đối với những người bạn đến đây đang tìm cách loại bỏ khỏi một loạt các đối tượng và sử dụng lodash, bạn có thể làm một cái gì đó như thế này:


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

Lưu ý: Bạn không cần phải hủy nếu bạn không muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.