it-swarm.com.ru

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

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

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

81
user1082754

Вы можете сделать свой собственный плагин подчеркивания (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указано , этот миксин влияет на исходный объект, в то время как оригинальный метод подчеркивания compactвозвращает копию массива .
Чтобы решить эту проблему и заставить нашу compactObject вести себя более как cousin, вот небольшое обновление: 

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

Начиная с версии 1.7.0, вы можете использовать _.pick :

_.pick(sourceObj, _.identity)

Объяснение

Второй параметр _.pick может быть функцией предиката для выбора значений. Значения, для которых предикат возвращает правдивый, выбираются, а значения, для которых предикат возвращает ложный, игнорируются.

pick _.pick (объект, * ключи)

Возвращает копию object, отфильтрованного так, чтобы иметь значения только для белого списка keys (или массива допустимых ключей). В качестве альтернативы принимает предикат, указывающий, какие ключи выбрать.

_.identity - это вспомогательная функция, которая возвращает свой первый аргумент, что означает, что она также работает как функция предиката, которая выбирает истинные значения и отклоняет ложные. Библиотека Underscore также содержит множество других предикатов, например, _.pick(sourceObj, _.isBoolean) сохранит только логические свойства.

Если вы часто используете эту технику, вы можете сделать ее более выразительной:

var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);

Подчеркнутая версия 1.6.0 также предоставила _.pick, но она не принимала функцию предиката вместо белого списка.

166
Emil Lundberg

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

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

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

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

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

43
Shwaydogg

С помощью Лодаша Преобразование ,

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});
21
raine
Object.keys(o).forEach(function(k) {
    if (!o[k]) {
        delete o[k];
    }
});
17
Florian Margaine

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

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

для использования объекта удалить.

for(var k in obj){

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

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

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

1
Geoff Lee

в lodash вы делаете так:

_.pickBy(object, _.identity);
0
Hydrogen