Tôi có một đối tượng với một số thuộc tính. Tôi muốn xóa bất kỳ thuộc tính nào có giá trị sai.
Điều này có thể đạt được với compact
mảng, nhưng đối với đối tượng thì sao?
Tôi có một đối tượng với một số thuộc tính. Tôi muốn xóa bất kỳ thuộc tính nào có giá trị sai.
Điều này có thể đạt được với compact
mảng, nhưng đối với đối tượng thì sao?
Câu trả lời:
Bạn có thể tạo plugin gạch dưới (mixin) của riêng mình:
_.mixin({
compactObject: function(o) {
_.each(o, function(v, k) {
if(!v) {
delete o[k];
}
});
return o;
}
});
Và sau đó sử dụng nó như một phương pháp gạch dưới gốc:
var o = _.compactObject({
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined
});
Như @AndreiNeculau đã chỉ ra , mixin này ảnh hưởng đến đối tượng gốc, trong khi compact
phương thức gạch dưới gốc trả về bản sao của mảng .
Để giải quyết vấn đề này và làm cho compactObject
hành vi của chúng tôi giống như anh em họ hơn , đây là một cập nhật nhỏ:
_.mixin({
compactObject : function(o) {
var clone = _.clone(o);
_.each(clone, function(v, k) {
if(!v) {
delete clone[k];
}
});
return clone;
}
});
_.compact
. Nó sẽ xóa các thuộc tính, thay vì tạo một bản sao nông chỉ với các giá trị trung thực. Xem stackoverflow.com/a/19750822/465684 bên dưới
delete
nói chung không được khuyến khích vì nó ngay lập tức làm lộ ra các thuộc tính có cùng tên từ chuỗi nguyên mẫu và cũng ảnh hưởng đến hiệu suất do "lớp ẩn" (V8) - việc thay đổi cấu trúc đối tượng khiến động cơ phải làm việc thêm. Giải pháp tốt nhất và ngắn nhất sẽ là _.pick(o, _.identity)
.
Kể từ phiên bản Underscore 1.7.0, bạn có thể sử dụng _.pick
:
_.pick(sourceObj, _.identity)
Tham số thứ hai _.pick
có thể là một hàm vị từ để chọn giá trị. Các giá trị mà vị từ trả về true được chọn và các giá trị mà vị từ trả về falsy bị bỏ qua.
pick _.pick (đối tượng, phím *)
Trả lại bản sao của đối tượng , được lọc để chỉ có các giá trị cho các khóa trong danh sách trắng (hoặc mảng khóa hợp lệ). Ngoài ra, chấp nhận một vị từ cho biết phím nào cần chọn.
_.identity
là một hàm trợ giúp trả về đối số đầu tiên của nó, có nghĩa là nó cũng hoạt động như một hàm vị từ để chọn các giá trị trung thực và loại bỏ các giá trị sai. Thư viện Underscore cũng đi kèm với một loạt các vị từ khác, chẳng hạn như _.pick(sourceObj, _.isBoolean)
sẽ chỉ giữ lại các thuộc tính boolean.
Nếu bạn sử dụng kỹ thuật này nhiều, bạn có thể muốn làm cho nó biểu cảm hơn một chút:
var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);
Dấu gạch dưới phiên bản 1.6.0 cũng được cung cấp _.pick
, nhưng nó không chấp nhận một hàm vị ngữ thay vì một danh sách trắng.
_.identity
chức năng, rất tiện dụng.
_.omit(sourceObj, _.isUndefined)
để loại bỏ chỉ các giá trị không xác định (cho phép false, null, 0).
pick(obj, Boolean)
để loại bỏ các giá trị falsey rằng cách tiếp cận tương tự có thể được sử dụng khi arr.filter(Boolean)
để làm sạch một mảng từ các giá trị falsey ...
_.pick(sourceObj, prop => prop)
_.pick
tác phẩm với những cái tên bất động sản, cho chức năng này như đã đề cập trong bài viết sử dụng_.pickBy
_.omitBy( source, i => !i );
Điều này được phát biểu theo kiểu nghịch đảo với câu trả lời của Emil. Bằng cách này imho đọc rõ ràng hơn; nó tự giải thích hơn.
Hơi kém sạch sẽ nếu bạn không có sự sang trọng của ES6: _.omitBy( source, function(i){return !i;});
_.omitBy( source, _.isEmpty)
Việc sử dụng _.isEmpty
, thay vì tính xác _.identity
thực, cũng sẽ thuận tiện loại bỏ các mảng và đối tượng trống khỏi bộ sưu tập và có thể loại bỏ số và ngày một cách bất tiện . Do đó, kết quả KHÔNG phải là câu trả lời chính xác cho câu hỏi của OP, tuy nhiên nó có thể hữu ích khi tìm cách loại bỏ các tập hợp rỗng.
omitBy
. lodash.com/docs#omitBy
_.pick(source, i => i);
mà tránh sự phủ định
_.pickBy(source)
là tất cả những gì cần thiết.
_.isEmpty(5) === true
. Do đó các giá trị là số sẽ bị loại bỏ.
Với sự biến đổi của lodash ,
_.transform(obj, function(res, v, k) {
if (v) res[k] = v;
});
var compactObject = _.partialRight(_.pick, _.identity);
_.pickBy(object)
là tất cả những gì bạn cần
Object.keys(o).forEach(function(k) {
if (!o[k]) {
delete o[k];
}
});
.keys
và .forEach
.
forEach
phương pháp JS
Đột nhiên, tôi cần tạo một hàm để loại bỏ các lỗi sai đệ quy. Tôi hi vọng cái này giúp được. Tôi đang sử dụng Lodash.
var removeFalsies = function (obj) {
return _.transform(obj, function (o, v, k) {
if (v && typeof v === 'object') {
o[k] = _.removeFalsies(v);
} else if (v) {
o[k] = v;
}
});
};
_.mixin({ 'removeFalsies': removeFalsies });
Sau đó, bạn có thể sử dụng nó:
var o = _.removeFalsies({
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined,
obj: {
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined
}
});
// {
// foo: 'bar',
// obj: {
// foo: 'bar'
// }
// }
Để thêm vào câu trả lời của gion_13:
_.mixin({
compactObject : function(o) {
var newObject = {};
_.each(o, function(v, k) {
if(v !== null && v !== undefined) {
newObject[k] = v
}
});
return newObject;
}
});
Điều này tạo một đối tượng mới và thêm các khóa và giá trị thay vì sao chép mọi thứ và xóa các cặp khóa-giá trị. Sự khác biệt nhỏ.
Nhưng quan trọng hơn, hãy kiểm tra rõ ràng giá trị null và undefined thay vì falsey, điều này sẽ xóa các cặp khóa-giá trị có giá trị false.
trong lodash bạn làm như thế này:
_.pickBy(object, _.identity);
Mặc dù _.compact
được tài liệu hóa để sử dụng trong mảng. Nó dường như cũng hoạt động cho các đối tượng. Tôi vừa chạy phần sau trong bảng điều khiển chrome, opera và firefox:
var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)
[1, 3, function()]
CẬP NHẬT: Vì mẫu cho biết việc gọi _.compact
một đối tượng sẽ làm rơi các phím và trả về một mảng đã nén.