我有两个javascript对象:
var a = {
x: 1,
y: {
faz: 'hello',
baz: ''
},
z: [1, 2]
};
var defaults = {
x: 2,
y: {
faz: '',
baz: ''
},
z: [1, 2]
};
我希望仅保留不同的a
字段与默认值:
a = remove_defaults(a, defaults); // <---- i need this fnc
{
x: 1,
y: {
faz: 'hello'
}
}
目标是从作为状态的对象中删除默认值(通过URL)。状态可以有嵌套字段,因此浅层比较是不够的。叶子值都是原始的(数字,字符串,布尔)。
(这与underscore.js
的{{1}}方法略有不同)
实现这一目标的最佳方法是什么?
如果有帮助,解决方案可以使用_.defaults()
,但不能使用underscore.js
。
答案 0 :(得分:3)
试试这个:
function removeDuplicates(a, defaults, result) {
for (var i in a) {
if (i in defaults) {
if (typeof a[i] == "object"
&& typeof defaults[i] == "object"
&& Object.prototype.toString.call(defaults[i]) !== '[object Array]') {
result[i] = removeDuplicates(a[i], defaults[i], {});
} else if (a[i] !== defaults[i]) {
result[i] = a[i];
}
} else {
result[i] = a[i];
}
}
return result;
}
var result = removeDuplicates(a, defaults, {});
答案 1 :(得分:1)
function remove_defaults(obj, defaults) {
for (var i in obj) {
if (typeof obj[i] == 'object') {
obj[i] = remove_defaults(obj[i], defaults[i]);
continue;
}
if (defaults[i] !== undefined && obj[i] == defaults[i]) {
delete obj[i];
}
}
return obj;
}
答案 2 :(得分:0)
我自己的看法:
function no_defaults(obj, defaults) {
if ((obj instanceof Array) && (defaults instanceof Array)) {
var result = _.difference(obj, defaults);
return _.isEmpty(result) ? undefined : result;
}
if ((obj instanceof Array) || (defaults instanceof Array))
return _.clone(obj);
if (typeof obj == "object" && typeof defaults == "object") {
var result = {};
for (var prop in obj) {
var res = prop in defaults ? no_defaults(obj[prop], defaults[prop]) : _.clone(obj[prop]);
if (res !== undefined)
result[prop] = res;
}
return _.isEmpty(result) ? undefined : result;
}
return _.isEqual(obj, defaults) ? undefined : _.clone(obj);
}
请注意这个深度处理对象,但不是数组。数组仅针对其直接元素的浅层差异进行处理 - 如果元素本身需要no_default
,则此函数不会执行。但这对我的预期用例来说很好。