У меня есть объект с несколькими свойствами. Я хотел бы удалить любые свойства, имеющие значения фальши.
Это может быть достигнуто с помощью compact
на массивах, но как насчет объектов?
У меня есть объект с несколькими свойствами. Я хотел бы удалить любые свойства, имеющие значения фальши.
Это может быть достигнуто с помощью compact
на массивах, но как насчет объектов?
Вы можете создать свой собственный подстрочный плагин (mixin):
_.mixin({
compactObject: function(o) {
_.each(o, function(v, k) {
if(!v) {
delete o[k];
}
});
return o;
}
});
И затем используйте его как собственный метод подчеркивания:
var o = _.compactObject({
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined
});
Как указано @AndreiNeculau , этот mixin влияет на исходный объект, тогда как оригинальный compact
метод подчеркивания возвращает копию массива.
Чтобы решить эту проблему и сделать наш compactObject
более похожим на кузена, здесь небольшое обновление:
_.mixin({
compactObject : function(o) {
var clone = _.clone(o);
_.each(clone, function(v, k) {
if(!v) {
delete clone[k];
}
});
return clone;
}
});
С Underscore версии 1.7.0 вы можете использовать _.pick
:
_.pick(sourceObj, _.identity)
Второй параметр _.pick
может быть предикатной функцией для выбора значений. Значения, для которых предикат возвращает правду, выбираются, а значения, для которых предикат возвращает фальши, игнорируются.
выберите _.pick(объект, * ключи)
Вернуть копию объекта , отфильтровать, чтобы иметь только значения для белых ключей (или массива действительных ключей). Альтернативно принимает предикат, указывающий, какие ключи выбрать.
_.identity
- вспомогательная функция, которая возвращает свой первый аргумент, что означает, что он также работает как предикатная функция, которая выбирает правдивые значения и отклоняет ложные. Библиотека Underscore также содержит множество других предикатов, например _.pick(sourceObj, _.isBoolean)
сохранит только логические свойства.
Если вы используете этот метод много, вы можете сделать его более выразительным:
var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);
Underscore версии 1.6.0 предоставил _.pick
, но он не принял функцию предиката вместо белого списка.
_.omit( source, i => !i );
Это указано обратным образом к ответу Эмиля. Таким образом, imho читается более четко; это более объяснительно.
Чуть менее чистый, если у вас нет роскоши ES6: _.omit( source, function(i){return !i;});
_.omit( source, _.isEmpty)
Используя _.isEmpty
вместо _.identity
для правды, также удобно удаляет пустые массивы и объекты из коллекции и, возможно, неудобно удаляет числа и даты. Таким образом, результат НЕ является точным ответом на вопрос ОП, однако это может быть полезно, если вы хотите удалить пустые коллекции.
С lodash transform,
_.transform(obj, function(res, v, k) {
if (v) res[k] = v;
});
Object.keys(o).forEach(function(k) {
if (!o[k]) {
delete o[k];
}
});
Вы можете создать неглубокий клон:
_(obj).reduce(function(a,v,k){
if(v){ a[k]=v; }
return a;
},{});
для удаления объекта.
for(var k in obj){
if(obj.hasOwnProperty(k) && !obj[k]){
delete obj[k];
}
}
Вдруг мне понадобилось создать функцию для удаления рекурсивных фальсификаций. Надеюсь, это поможет. Я использую 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 });
Затем вы можете использовать его:
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'
// }
// }
Чтобы добавить ответ gion_13:
_.mixin({
compactObject : function(o) {
var newObject = {};
_.each(o, function(v, k) {
if(v !== null && v !== undefined) {
newObject[k] = v
}
});
return newObject;
}
});
Это создает новый объект и добавляет ключи и значения вместо клонирования всего и удаления пар ключ-значение. Малая разница.
Но что более важно, проверяет явно для null и undefined вместо falsey, что приведет к удалению пар ключ-значение, которые имеют значение false.
Хотя _.compact
документируется для использования в массивах. Кажется, он работает и для объектов. Я просто запустил следующее в консолях Chrome, Opera и Firebox:
var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)
[1, 3, function()]
UPDATE: когда образец указывает на вызов _.compact
, объект отбрасывает ключи и возвращает сжатый массив.