У меня есть объект с несколькими свойствами. Я хочу удалить все свойства с ложными значениями.
Этого можно добиться с помощью 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 , этот миксин влияет на исходный объект, в то время как исходный метод подчеркивания возвращает копию массива . Чтобы решить эту проблему и заставить нас вести себя как кузен , вот небольшое обновление:
compact
compactObject
_.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
может быть функцией предиката для выбора значений. Выбираются значения, для которых предикат возвращает истинность , а значения, для которых предикат возвращает ложь , игнорируются._.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
вместо_.pick
)_.pickBy(object)
это все, что вам нужноObject.keys(o).forEach(function(k) { if (!o[k]) { delete o[k]; } });
источник
.keys
и.forEach
.forEach
метод JSВы можете создать неглубокий клон:
_(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.
источник
в lodash вы делаете это так:
источник
Хотя
_.compact
задокументирован для использования в массивах. Кажется, это работает и для объектов. Я только что запустил следующее в консолях chrome, opera и firefox:var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}} undefined _.compact(obj) [1, 3, function()]
ОБНОВЛЕНИЕ: как показано в образце, вызов
_.compact
объекта приведет к удалению ключей и возврату сжатого массива.источник