深克隆没有一些领域



让我们有下一个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"]);

这是一个独立的函数,依赖于lodash/underscore,我写的,做同样的事情。

为对象或数组中的每个(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 ]

最新更新