我对lodash并不陌生,并创建了一个函数,该函数从值为null或空白的对象中删除键。 但是,当我传递包含一部分作为数组的对象时,它将删除数组并将其转换为对象。
下面是我尝试的代码:
_.mixin({ 'removeFalsies': this.removeFalsies });
_.mixin({
removeEmptyObjects: this.removeEmptyObjects
});
removeFalsies (obj) {
return _.transform(obj, function (o, v, k) {
if (v && typeof v === 'object') {
if (v !== '') {
o[k] = _.removeFalsies(v);
}
} else if (v === false) {
o[k] = v;
} else if (v) {
o[k] = v;
}
});
}
removeEmptyObjects (obj) {
return _(obj)
.pickBy(_.isObject)
.mapValues(_.removeEmptyObjects)
.omitBy(_.isEmpty)
.assign(_.omitBy(obj, _.isObject))
.value();
}
下面是我提供的JSON,可省略空白和null值,因此它应将“ smallMap”对象中的所有属性作为系列删除,align为空白对象,并且还应删除高度。
另一方面,它应该删除规则中的“ mid”以及子数组中的series1。
var finalProp = {
"smallMap": {
"series": {},
"align": {},
"height": ""
},
"series": [
{
"heatRules": [
{
"min": "#555",
"mid": null
}
],
"mapPolygons": {
"tooltipText": "{name}",
"togglable": true
},
"id": "value"
}
],
"children": [
{
"type": "HeatLegend",
"width": "100%",
"series1": null
}
]
}
_.removeEmptyObjects(_.removeFalsies(finalProp));
它正在按预期方式删除所有内容,但只有1个问题正在将数组转换为对象。
它在下面提供了错误的输出,而不是序列:{0:{}},它应该提供序列:[{}],而不是子项:{0:{}},它应该提供[{}]。
{
"series": {
"0": {
"heatRules": {
"0": {
"min": "#555"
}
},
"mapPolygons": {
"tooltipText": "{name}",
"togglable": true
},
"id": "value"
}
},
"children": {
"0": {
"type": "HeatLegend",
"width": "100%"
}
}
}
我找不到任何帮助的问题所在。
答案 0 :(得分:1)
问题出在函数removeFalsies
中,在该函数中您无法正确考虑数组。请记住,数组也是对象,对if (v && typeof v === 'object')
的检查还不够。
发生的事情是您要做的:
if (v && typeof v === 'object') {
if (v !== '') {
o[k] = _.removeFalsies(v);
}
}
当您在其中传递_.transform
的数组时,k
是0
,最后创建的对象是key
0,其值就是{{1} }
只需在该_.removeFalsies(v);
中插入一个断点或debugger
,您就可以轻松地看到问题所在。
还请注意,lodash已经拥有许多方法来检查诸如if
以及数组_.isObject
... _.isArray
和_.isString
等对象。
答案 1 :(得分:1)
主要存在两个问题,@ Akrion提到了其中一个问题,您可以执行以下操作:
removeFalsies (obj) {
return _.transform(obj, function (o, v, k, l) {
// here you have to check for array also as typeof will return object for array also
if (v && _.isObject(v) && !_.isArray(v)) {
if (v !== '' && !_.omitBy(v, _.isObject)) {
o[k] = removeFalsies(v);
}
} else if(_.isArray(v)) {
if(!o.hasOwnProperty(k)) o[k] = [];
//And if it is array loop through it
_.forEach(v, function(v1, k1) {
o[k].push(removeFalsies(v1));
});
} else if (v === false) {
o[k] = v;
} else if (v) {
o[k] = v;
}
});
}
在调用函数时,只需尝试删除mapValues即可创建对象并在对象中转换数组,因为您的键0已转换为键
removeEmptyObjects =function (obj) {
return _(obj).pickBy(_.isObject).omitBy(_.isEmpty).assign(_.omitBy(obj, _.isObject)).value();
}
希望这对您有所帮助,只是简短说明而未正确测试。
答案 2 :(得分:0)
如果您的代码使用
typeof v === 'object'
它将为true
返回arrays
。
要检查array
,请使用
Array.isArray(t)
将array
处理为object
并遍历键会导致问题。
function removeFalsies(obj) {
return _.transform(obj, function(o, v, k, l) {
if (Array.isArray(obj) {
for (let arrItem of obj) {
removeFalsies(arrItem);
}
return
}
// else not array...
})
}