让我下一个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
}
你知道简单的解决方案?
如果你不介意加入到对象的原型,这是一个简单的解决方案。 您可能要修改一些供自己使用。
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"]);
Here is a standalone function depending on lodash/underscore that i've written that does the same.
It calls a callback for each (value, indexOrKey) pair in the object or array and if true will omit that pair in the resulting object.
The callback is called after the value has been visited so you can omit a whole sub-tree of values that match your condition.
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;
}
Some samples
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 ]