让我有下一个javascript对象。现在我想克隆它,但没有一些字段。例如,我想要没有字段"lastName"
和"cars.age"
的克隆对象
的输入
{
"firstName":"Fred",
"lastName":"McDonald",
"cars":[
{
"type":"mersedes",
"age":5
},
{
"model":"bmw",
"age":10
}
]
}
输出(克隆)
{
"firstName":"Fred",
"cars":[
{
"model":"mersedes"
},
{
"model":"bmw"
}
]
}
我可以做类似
的事情var human = myJson
var clone = $.extend(true, {}, human)
delete clone.lastName
_.each(clone.cars, function(car))
{
delete car.age
}
您知道更简单的解决方案吗?
答案 0 :(得分:6)
如果您不介意添加对象原型,这是一个简单的解决方案。您可能需要修改一些以供自己使用。
Object.prototype.deepOmit = function(blackList) {
if (!_.isArray(blackList)) {
throw new Error("deepOmit(): argument must be an Array");
}
var copy = _.omit(this, blackList);
_.each(blackList, function(arg) {
if (_.contains(arg, '.')) {
var key = _.first(arg.split('.'));
var last = arg.split('.').slice(1);
copy[key] = copy[key].deepOmit(last);
}
});
return copy;
};
Array.prototype.deepOmit = function(blackList) {
if (!_.isArray(blackList)) {
throw new Error("deepOmit(): argument must be an Array");
}
return _.map(this, function(item) {
return item.deepOmit(blackList);
});
};
然后当你有一个像这样的对象时:
var personThatOwnsCars = {
"firstName":"Fred",
"lastName":"McDonald",
"cars":[
{
"type":"mersedes",
"age":5
},
{
"model":"bmw",
"age":10
}
]
};
你可以做这样的魔法。
personThatOwnsCars.deepOmit(["firstName", "cars.age"]);
甚至像这样的魔法!
[person1, person2].deepOmit(["firstName", "cars.age"]);
答案 1 :(得分:5)
这是一个独立的函数,取决于我写的lodash /下划线也是如此。
它为对象或数组中的每个(value,indexOrKey)对调用一个回调,如果为true,则在结果对象中省略该对。
在访问该值后调用回调,因此您可以省略与您的条件匹配的整个子树。
function deepOmit(sourceObj, callback, thisArg) {
var destObj, i, shouldOmit, newValue;
if (_.isUndefined(sourceObj)) {
return undefined;
}
callback = thisArg ? _.bind(callback, thisArg) : callback;
if (_.isPlainObject(sourceObj)) {
destObj = {};
_.forOwn(sourceObj, function(value, key) {
newValue = deepOmit(value, callback);
shouldOmit = callback(newValue, key);
if (!shouldOmit) {
destObj[key] = newValue;
}
});
} else if (_.isArray(sourceObj)) {
destObj = [];
for (i = 0; i <sourceObj.length; i++) {
newValue = deepOmit(sourceObj[i], callback);
shouldOmit = callback(newValue, i);
if (!shouldOmit) {
destObj.push(newValue);
}
}
} else {
return sourceObj;
}
return destObj;
}
一些样本
var sourceObj = {
a1: [ undefined, {}, { o: undefined } ],
a2: [ 1, undefined ],
o: { s: 's' }
};
deepOmit(sourceObj, function (value) {
return value === undefined;
});
//=> { a1: [ {}, {} ], a2: [ 1 ], o: { s: 's' }}
//omit empty objects and arrays too
deepOmit(sourceObj, function (value) {
return value === undefined ||
(_.isPlainObject(value) && !_.keys(value).length) ||
(_.isArray(value) && !value.length);
});
//=> { a2: [ 1 ], o: { s: 's' }}
//indexOrKey is the string key or the numeric index if the object is array
deepOmit([ 0, 1, 2, 3, 4 ], function (value, indexOrKey) {
return indexOrKey % 2;
});
//=> [ 0, 2, 4 ]