Bir JavaScript nesnesindeki undefined
veya null
bir JavaScript nesnesindeki tüm öznitelikleri nasıl kaldırabilirim ?
(Soru benzer bu bir Diziler için)
Bir JavaScript nesnesindeki undefined
veya null
bir JavaScript nesnesindeki tüm öznitelikleri nasıl kaldırabilirim ?
(Soru benzer bu bir Diziler için)
Yanıtlar:
Nesne üzerinde döngü yapabilirsiniz:
var test = {
test1 : null,
test2 : 'somestring',
test3 : 3,
}
function clean(obj) {
for (var propName in obj) {
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
}
clean(test);
Bu mülk kaldırma işleminin nesnenin prototip zincirini çalıştırmadığından endişe ediyorsanız, şunları da yapabilirsiniz:
function clean(obj) {
var propNames = Object.getOwnPropertyNames(obj);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
}
Null ve undefined hakkında birkaç not:
test.test1 === null; // true
test.test1 == null; // true
test.notaprop === null; // false
test.notaprop == null; // true
test.notaprop === undefined; // true
test.notaprop == undefined; // true
Bazı ES6 / ES2015 kullanma :
1) Öğeleri atamadan satır içi kaldırmak için basit bir astar :
Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);
2) Bu örnek kaldırıldı ...
3) Fonksiyon olarak yazılan ilk örnek:
const removeEmpty = obj => {
Object.keys(obj).forEach(key => obj[key] == null && delete obj[key]);
};
4) Bu işlev , iç içe nesnelerden de öğeleri silmek için özyineleme kullanır :
const removeEmpty = obj => {
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === "object") removeEmpty(obj[key]); // recurse
else if (obj[key] == null) delete obj[key]; // delete
});
};
4b) Bu 4'e benzer), ancak kaynak nesneyi doğrudan değiştirmek yerine yeni bir nesne döndürür.
const removeEmpty = obj => {
const newObj = {};
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === "object") {
newObj[key] = removeEmpty(obj[key]); // recurse
} else if (obj[key] != null) {
newObj[key] = obj[key]; // copy value
}
});
return newObj;
};
5) 4b'ye işlevsel bir yaklaşım) @ MichaelJ.Zoidl'infilter()
ve kullanarak cevabına dayanır reduce()
. Bu da yeni bir nesne döndürür:
const removeEmpty = obj =>
Object.keys(obj)
.filter(k => obj[k] != null) // Remove undef. and null.
.reduce(
(newObj, k) =>
typeof obj[k] === "object"
? { ...newObj, [k]: removeEmpty(obj[k]) } // Recurse.
: { ...newObj, [k]: obj[k] }, // Copy value.
{}
);
6) 4 ile aynı) ancak ES7 / 2016 ile Object.entries()
.
const removeEmpty = (obj) =>
Object.entries(obj).forEach(([key, val]) => {
if (val && typeof val === 'object') removeEmpty(val)
else if (val == null) delete obj[key]
})
5b)
Özyineleme kullanan ve ES2019 ile yeni bir nesne döndüren başka bir işlevsel sürüm : Object.fromEntries()
const removeEmpty = obj =>
Object.fromEntries(
Object.entries(obj)
.filter(([k, v]) => v != null)
.map(([k, v]) => (typeof v === "object" ? [k, removeEmpty(v)] : [k, v]))
);
7) 4 ile aynı) ancak düz ES5'te :
function removeEmpty(obj) {
Object.keys(obj).forEach(function(key) {
if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
else if (obj[key] == null) delete obj[key]
});
};
keys
olan ve object
bu yüzden açık olan bir işlevdir . Ama sanırım bu bir zevk meselesi. o
k
Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})
Lodash veya underscore.js kullanıyorsanız, işte basit bir çözüm:
var obj = {name: 'John', age: null};
var compacted = _.pickBy(obj);
Bu sadece lodash 4, pre lodash 4 veya underscore.js ile çalışır _.pick(obj, _.identity)
;
_.omit(obj, _.isUndefined)
daha iyidir.
_.isUndefined
, _.omitBy(obj, _.isNil)
her ikisini de atlamak için kullanın undefined
venull
ES6 + için en kısa bir astar
Tüm falsy değerleri Filtre ( ""
, 0
, false
, null
, undefined
)
Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})
Filtre null
ve undefined
değerler:
Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})
SADECE Filtrele null
Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})
SADECE Filtrele undefined
Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})
Özyinelemeli Çözümler: Filtreler null
veundefined
Nesneler için:
const cleanEmpty = obj => Object.entries(obj)
.map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
.reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});
Nesneler ve Diziler için:
const cleanEmpty = obj => {
if (Array.isArray(obj)) {
return obj
.map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
.filter(v => !(v == null));
} else {
return Object.entries(obj)
.map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
.reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
}
}
v == null
karşı kontrol edecektir . undefined
null
cleanEmpty
recursve çözeltiler boş bir nesne döndürür {}
tarihi nesneler için
Birisinin Owen'in (ve Eric'in) cevabının özyinelemeli bir versiyonuna ihtiyacı varsa, işte burada:
/**
* Delete all null (or undefined) properties from an object.
* Set 'recurse' to true if you also want to delete properties in nested objects.
*/
function delete_null_properties(test, recurse) {
for (var i in test) {
if (test[i] === null) {
delete test[i];
} else if (recurse && typeof test[i] === 'object') {
delete_null_properties(test[i], recurse);
}
}
}
hasOwnProperty
kullanarak kontrol etmelisinizif(test.hasOwnProperty(i)) { ... }
JSON.stringify tanımlanmamış anahtarları kaldırır.
removeUndefined = function(json){
return JSON.parse(JSON.stringify(json))
}
null
olarak tedavi edilmesi undefined
daha fazla bilgi için, kullanım yerine fonksiyonunu bu cevaba bakın: stackoverflow.com/questions/286141/...
null
değerleri kaldırmayacağını unutmayın . Deneyin: let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }
ve sonra console.log(removeUndefined(a))
. Soru undefined
ve null
değerler hakkındaydı.
JSON.stringify
Replacer parametresinin bir kombinasyonunu kullanabilir ve JSON.parse
bir nesneye geri dönüştürebilirsiniz. Bu yöntemin kullanılması, iç içe nesneler içindeki tüm iç içe anahtarların değiştirilmesinin de yapıldığı anlamına gelir.
Örnek Nesne
var exampleObject = {
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3],
object: {
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3]
},
arrayOfObjects: [
{
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3]
},
{
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3]
}
]
};
Replacer İşlevi
function replaceUndefinedOrNull(key, value) {
if (value === null || value === undefined) {
return undefined;
}
return value;
}
Nesneyi Temizle
exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);
Kullanılması Ramda # pickBy tüm kaldıracak null
, undefined
ve false
değerleri:
const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)
@Manroe'nin belirttiği gibi, false
değerleri kullanmak için isNil()
:
const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)
(v) => !R.isNil(v)
Muhtemelen OP'nin sorusu için daha iyi bir seçimdir, false
ya da diğer sahte değerler de reddedilirseR.identity
İşlevsel ve değişmez yaklaşım, .filter
gerekenden daha fazla nesne yaratmadan veya yaratmadan
Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})
obj[key] === undefined
içinobj[key] === undefined || obj[key] === null
const omitFalsy = obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...(obj[key] && { [key]: obj[key] }) }), {});
Json.stringify'ın replacer argümanını kullanarak bir satırda yinelemeli kaldırma yapabilirsiniz
const removeEmptyValues = obj => (
JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)
Kullanımı:
removeEmptyValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}
Emmanuel'in yorumunda belirtildiği gibi, bu teknik yalnızca veri yapınız yalnızca JSON formatına (dizeler, sayılar, listeler, vb.) Yerleştirilebilecek veri türleri içeriyorsa işe yaradı.
(Bu cevap yeni kullanmaya güncellendi Nullish Birleştirme operatörü tarayıcı desteği ihtiyaçlarına bağlı olarak yerine bu işlevi kullanmak isteyebilirsiniz. (k,v) => v!=null ? v : undefined
)
NaN
için null
kaldırılmaz hangi.
!
durum ile daha kısa yapabilirsiniz
var r = {a: null, b: undefined, c:1};
for(var k in r)
if(!r[k]) delete r[k];
Kullanımda hatırlayın: @semicolor'un yorumlarda duyurduğu gibi: Değer, yanlış veya sıfır boş bir dize ise özellikleri de siler
[null, undefined].includes(r[k])
kullanın !r[k]
.
Daha kısa ES6 saf çözümü, bir diziye dönüştürün, filtre işlevini kullanın ve bir nesneye geri dönüştürün. Ayrıca bir işlev yapmak kolay olurdu ...
Btw. bu ile .length > 0
boş bir dize / dizi olup olmadığını kontrol, bu yüzden boş anahtarları kaldıracak.
const MY_OBJECT = { f: 'te', a: [] }
Object.keys(MY_OBJECT)
.filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
.reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});
null
ve undefined
sadece kullanımı daha kolay olurdu MY_OBJECT[f] != null
. Geçerli çözümünüz, boş olmayan dizeler / listeler hariç her şeyi kaldırır ve değerler olduğunda bir hata atarnull
filter
, daha okunabilir olurdu.
omit
, çağırmadan önce obj var kontrol etmelisiniz Object.keys
:const omit = (obj, filter) => obj && Object.keys(obj).filter(key => !filter(obj[key])).reduce((acc,key) => {acc[key] = obj[key]; return acc}, {});
4 satır saf ES7 çözümü istiyorsanız:
const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
if (typeof v === 'boolean' || v) o[k] = clean(v);
return o;
}, e instanceof Array ? [] : {}) : e;
Veya daha okunabilir sürümü tercih ediyorsanız:
function filterEmpty(obj, [key, val]) {
if (typeof val === 'boolean' || val) {
obj[key] = clean(val)
};
return obj;
}
function clean(entry) {
if (entry instanceof Object) {
const type = entry instanceof Array ? [] : {};
const entries = Object.entries(entry);
return entries.reduce(filterEmpty, type);
}
return entry;
}
Bu, boole değerlerini koruyacak ve dizileri de temizleyecektir. Temizlenmiş bir kopya döndürerek orijinal nesneyi de korur.
Projemde aynı senaryo var ve aşağıdaki yöntemi kullanarak elde ettim.
Tüm veri türleriyle çalışır, yukarıda belirtilen az sayıda tarih ve boş dizilerle çalışmaz.
removeEmptyKeysFromObject.js
removeEmptyKeysFromObject(obj) {
Object.keys(obj).forEach(key => {
if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
delete obj[key];
} else if (obj[key] && typeof obj[key] === 'object') {
this.removeEmptyKeysFromObject(obj[key]);
} else if (obj[key] == null || obj[key] === '') {
delete obj[key];
}
if (obj[key]
&& typeof obj[key] === 'object'
&& Object.keys(obj[key]).length === 0
&& Object.prototype.toString.call(obj[key]) !== '[object Date]') {
delete obj[key];
}
});
return obj;
}
herhangi bir nesneyi bu işleve ilet removeEmptyKeysFromObject ()
Derin bir arama için aşağıdaki kodu kullandım, belki bu soruya bakan herkes için yararlı olacaktır (döngüsel bağımlılıklar için kullanılamaz):
function removeEmptyValues(obj) {
for (var propName in obj) {
if (!obj[propName] || obj[propName].length === 0) {
delete obj[propName];
} else if (typeof obj[propName] === 'object') {
removeEmptyValues(obj[propName]);
}
}
return obj;
}
Yerinde mutasyon yapmak istemiyorsanız, ancak null / undefined kaldırılmış bir klonu döndürürseniz, ES6 azaltma işlevini kullanabilirsiniz.
// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
// Protect against null/undefined object passed in
return Object.keys(obj || {}).reduce((x, k) => {
// Check for null or undefined
if (obj[k] != null) {
x[k] = obj[k];
}
return x;
}, {});
}
Üzerinde piggypack için Ben'in cevap lodash en kullanarak bu sorunu çözmek için nasıl _.pickBy
:, ayrıca kardeş kütüphanede bu sorunu çözebilir Underscore.js 'ın _.pick
.
var obj = {name: 'John', age: null};
var compacted = _.pick(obj, function(value) {
return value !== null && value !== undefined;
});
Bakınız: JSFiddle Örneği
Birinin undefined
derin arama kullanarak bir nesneden değerleri kaldırması gerekiyorsa, lodash
işte kullandığım kod. Tüm boş değerleri ( null
/ undefined
) kaldırmak için değiştirmek oldukça basittir .
function omitUndefinedDeep(obj) {
return _.reduce(obj, function(result, value, key) {
if (_.isObject(value)) {
result[key] = omitUndefinedDeep(value);
}
else if (!_.isUndefined(value)) {
result[key] = value;
}
return result;
}, {});
}
Lodash ile:
_.omitBy({a: 1, b: null}, (v) => !v)
Eslint kullanıyorsanız ve param yeniden atama kuralını atlamaktan kaçınmak istiyorsanız, Object.assign öğesini oldukça zarif bir ES6 çözümü için .reduce ve hesaplanan özellik adıyla birlikte kullanabilirsiniz:
const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams)
.filter(key => queryParams[key] != null)
.reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }
nulls
ES6 kullanarak bir nesneyi yalnızca nesneyi mutasyona uğratmadan kaldırmanın işlevsel bir yolu reduce
:
const stripNulls = (obj) => {
return Object.keys(obj).reduce((acc, current) => {
if (obj[current] !== null) {
return { ...acc, [current]: obj[current] }
}
return acc
}, {})
}
stripNulls
akümülatör fonksiyonunun kapsamının dışından bir referans kullanır; ayrıca akümülatör fonksiyonu içinde filtreleyerek endişeleri karıştırır. Eg (örn. Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});
) Evet, filtrelenmiş ürünler üzerinde iki kez ilmek yapacak, ancak gerçekleşen mükemmel kayıp ihmal edilebilir.
...
Yayım sözdizimini aşağıdaki forEach
gibi bir şey kullanarak da kullanabilirsiniz :
let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};
Object.keys(obj).forEach(val => {
const newVal = obj[val];
cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});
console.info(cleanObj);
// General cleanObj function
const cleanObj = (valsToRemoveArr, obj) => {
Object.keys(obj).forEach( (key) =>
if (valsToRemoveArr.includes(obj[key])){
delete obj[key]
}
})
}
cleanObj([undefined, null], obj)
const getObjWithoutVals = (dontReturnValsArr, obj) => {
const cleanObj = {}
Object.entries(obj).forEach( ([key, val]) => {
if(!dontReturnValsArr.includes(val)){
cleanObj[key]= val
}
})
return cleanObj
}
//To get a new object without `null` or `undefined` run:
const nonEmptyObj = getObjWithoutVals([undefined, null], obj)
Bir nesneden boş öznitelikleri kaldırmak için JSON.stringify ve JSON.parse komutlarını kullanabiliriz.
jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
if (value == null || value == '' || value == [] || value == {})
return undefined;
return value;
});
{} != {}
ve [] != []
), ancak aksi takdirde yaklaşım geçerli
İşte kapsamlı bir özyinelemeli işlev (başlangıçta @chickens tarafından geliştirilen):
defaults=[undefined, null, '', NaN]
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
if (!defaults.length) return obj
if (defaults.includes(obj)) return
if (Array.isArray(obj))
return obj
.map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
.filter(v => !defaults.includes(v))
return Object.entries(obj).length
? Object.entries(obj)
.map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
.reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {})
: obj
}
KULLANIM:
// based off the recursive cleanEmpty function by @chickens.
// This one can also handle Date objects correctly
// and has a defaults list for values you want stripped.
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
if (!defaults.length) return obj
if (defaults.includes(obj)) return
if (Array.isArray(obj))
return obj
.map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
.filter(v => !defaults.includes(v))
return Object.entries(obj).length
? Object.entries(obj)
.map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
.reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {})
: obj
}
// testing
console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
a: 5,
b: 0,
c: undefined,
d: {
e: null,
f: [{
a: undefined,
b: new Date(),
c: ''
}]
},
g: NaN,
h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
a: 5,
b: 0,
c: undefined,
d: {
e: null,
f: [{
a: undefined,
b: '',
c: new Date()
}]
},
g: [0, 1, 2, 3, 4],
h: '',
}, [undefined, null]))
Saf / fonksiyonel yaklaşımı tercih ediyorsanız
const stripUndef = obj =>
Object.keys(obj)
.reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});