Удалить пустые свойства/значения фальшивки из объекта с помощью Underscore.js

У меня есть объект с несколькими свойствами. Я хотел бы удалить любые свойства, имеющие значения фальши.

Это может быть достигнуто с помощью compact на массивах, но как насчет объектов?

Ответ 1

Вы можете создать свой собственный подстрочный плагин (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
});

Update

Как указано @AndreiNeculau , этот mixin влияет на исходный объект, тогда как оригинальный compact метод подчеркивания возвращает копию массива.
Чтобы решить эту проблему и сделать наш compactObject более похожим на кузена, здесь небольшое обновление:

_.mixin({
  compactObject : function(o) {
     var clone = _.clone(o);
     _.each(clone, function(v, k) {
       if(!v) {
         delete clone[k];
       }
     });
     return clone;
  }
});

Ответ 2

С 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, но он не принял функцию предиката вместо белого списка.

Ответ 3

Quick 'n Clear: _.omit( source, i => !i );

Это указано обратным образом к ответу Эмиля. Таким образом, imho читается более четко; это более объяснительно.

Чуть менее чистый, если у вас нет роскоши ES6: _.omit( source, function(i){return !i;});

Альтернативный вариант: _.omit( source, _.isEmpty)

Используя _.isEmpty вместо _.identity для правды, также удобно удаляет пустые массивы и объекты из коллекции и, возможно, неудобно удаляет числа и даты. Таким образом, результат НЕ является точным ответом на вопрос ОП, однако это может быть полезно, если вы хотите удалить пустые коллекции.

Ответ 4

С lodash transform,

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});

Ответ 5

Object.keys(o).forEach(function(k) {
    if (!o[k]) {
        delete o[k];
    }
});

Ответ 6

Вы можете создать неглубокий клон:

_(obj).reduce(function(a,v,k){ 
     if(v){ a[k]=v; } 
     return a; 
},{});

Ответ 7

для удаления объекта.

for(var k in obj){

  if(obj.hasOwnProperty(k) && !obj[k]){
    delete obj[k];
  }
}

Ответ 8

Вдруг мне понадобилось создать функцию для удаления рекурсивных фальсификаций. Надеюсь, это поможет. Я использую 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'
//   }
// }

Ответ 9

Чтобы добавить ответ 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.

Ответ 10

Хотя _.compact документируется для использования в массивах. Кажется, он работает и для объектов. Я просто запустил следующее в консолях Chrome, Opera и Firebox:

var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)

[1, 3, function()]

UPDATE: когда образец указывает на вызов _.compact, объект отбрасывает ключи и возвращает сжатый массив.