У меня есть объект с несколькими свойствами. Я хочу удалить все свойства с ложными значениями.
Этого можно добиться с помощью compactмассивов, но как насчет объектов?
У меня есть объект с несколькими свойствами. Я хочу удалить все свойства с ложными значениями.
Этого можно добиться с помощью compactмассивов, но как насчет объектов?
Ответы:
Вы можете создать свой собственный плагин подчеркивания (миксин):
_.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 , этот миксин влияет на исходный объект, в то время как исходный метод подчеркивания возвращает копию массива .
Чтобы решить эту проблему и заставить нас вести себя как кузен , вот небольшое обновление:compactcompactObject
_.mixin({
compactObject : function(o) {
var clone = _.clone(o);
_.each(clone, function(v, k) {
if(!v) {
delete clone[k];
}
});
return clone;
}
});
_.compact. Он удалит свойства, а не создаст мелкий клон только с истинными значениями. См stackoverflow.com/a/19750822/465684 ниже
deleteобычно не рекомендуется, поскольку оно сразу же предоставляет свойства с тем же именем из цепочки прототипов, а также снижает производительность из-за «скрытых классов» (V8) - изменение структуры объекта заставляет движок выполнять дополнительную работу. Лучшее и самое короткое решение было бы _.pick(o, _.identity).
Начиная с версии Underscore 1.7.0, вы можете использовать _.pick:
_.pick(sourceObj, _.identity)
Второй параметр _.pickможет быть функцией предиката для выбора значений. Выбираются значения, для которых предикат возвращает истинность , а значения, для которых предикат возвращает ложь , игнорируются.
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, но она не принимает функцию предиката вместо белого списка.
_.identityфункции, очень удобно.
_.omit(sourceObj, _.isUndefined)для удаления только неопределенных значений (допускающих false, null, 0).
pick(obj, Boolean)для устранения ложных значений тот же подход, который можно использовать при arr.filter(Boolean)очистке массива от ложных значений ...
_.pick(sourceObj, prop => prop)
_.pickработает с именами свойств, для этой функции, как указано в посте, используется_.pickBy
_.omitBy( source, i => !i );Это сказано обратным ответу Эмиля. Таким образом imho читается яснее; это более понятно.
Чуть менее чистый, если у вас нет роскоши ES6: _.omitBy( source, function(i){return !i;});
_.omitBy( source, _.isEmpty)Использование _.isEmptyвместо _.identityправдивости также удобно удаляет из коллекции пустые массивы и объекты и, возможно, неудобно удаляет числа и даты . Таким образом, результат НЕ является точным ответом на вопрос OP, однако он может быть полезен при удалении пустых коллекций.
omitBy. lodash.com/docs#omitBy
_.pick(source, i => i); что позволяет избежать отрицания
_.pickBy(source)это все, что нужно.
_.isEmpty(5) === true. Таким образом значения, которые являются числами, будут отброшены.
С преобразованием lodash ,
_.transform(obj, function(res, v, k) {
if (v) res[k] = v;
});
var compactObject = _.partialRight(_.pick, _.identity);
_.pickBy(object)это все, что вам нужно
Object.keys(o).forEach(function(k) {
if (!o[k]) {
delete o[k];
}
});
.keysи .forEach.
forEachметод JS
Внезапно мне потребовалось создать функцию для удаления рекурсивных фальсификаций. Надеюсь, это поможет. Я использую 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.
в lodash вы делаете это так:
_.pickBy(object, _.identity);
Хотя _.compactзадокументирован для использования в массивах. Кажется, это работает и для объектов. Я только что запустил следующее в консолях chrome, opera и firefox:
var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)
[1, 3, function()]
ОБНОВЛЕНИЕ: как показано в образце, вызов _.compactобъекта приведет к удалению ключей и возврату сжатого массива.