У мене є об’єкт з декількома властивостями. Я хотів би видалити будь-які властивості, що мають хибні значення.
Цього можна досягти за допомогою 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 , цей міксин впливає на оригінальний об'єкт, тоді як метод оригінального підкреслення повертає копію масиву .
Щоб вирішити цю проблему та змусити нас поводитися більше, як двоюрідний брат , ось незначне оновлення: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(sourceObj, _.identity)
Другим параметром to _.pick
може бути функція предиката для вибору значень. Вибираються значення, для яких предикат повертає хибність , а значення, для яких предикат повертає хибність , ігноруються.
pick _.pick (об'єкт, * ключі)
Повернути копію об’єкта , відфільтровану, щоб мати значення лише для ключів із білого списку (або масиву дійсних ключів). В якості альтернативи приймає предикат, який вказує, які ключі вибрати.
_.identity
є допоміжною функцією, яка повертає свій перший аргумент, що означає, що вона також працює як предикатна функція, яка вибирає хибні значення та відхиляє хибні. Бібліотека підкреслення також має купу інших предикатів, наприклад _.pick(sourceObj, _.isBoolean)
, зберігатиме лише логічні властивості.
Якщо ви багато використовуєте цю техніку, можливо, ви хочете зробити її трохи виразнішою:
var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);
Також передбачена версія підкреслення 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
. Таким чином, значення, що є числами, будуть скинуті.
З перетворенням Лодаша ,
_.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
Ви можете створити неглибокий клон:
_(obj).reduce(function(a,v,k){
if(v){ a[k]=v; }
return a;
},{});
Раптом мені потрібно було створити функцію для видалення рекурсивних фальшивок. Сподіваюся, це допоможе. Я використовую 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.
у лодаші ви робите так:
_.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
об’єкта скине ключі та поверне ущільнений масив.