Skip to content

Commit

Permalink
feat(copyDeep): duplicate only recursive instances
Browse files Browse the repository at this point in the history
  • Loading branch information
medikoo committed Oct 13, 2017
1 parent 270a983 commit bba529a
Showing 1 changed file with 24 additions and 27 deletions.
51 changes: 24 additions & 27 deletions object/copy-deep.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,37 @@
var forEach = require("./for-each")
, isPlainObject = require("./is-plain-object")
, ensureValue = require("./valid-value")
, isArray = Array.isArray
, copy
, copyItem;
, isArray = Array.isArray;

copyItem = function (value) {
var index;
if (!isPlainObject(value) && !isArray(value)) return value;
index = this[0].indexOf(value);
if (index === -1) return copy.call(this, value);
return this[1][index];
};
var copyValue = function (value, ancestors, ancestorsCopy) {
var mode;
if (isPlainObject(value)) mode = "object";
else if (isArray(value)) mode = "array";
if (!mode) return value;

var copy = ancestorsCopy[ancestors.indexOf(value)];
if (copy) return copy;
copy = mode === "object" ? {} : [];

copy = function (source) {
var target = isArray(source) ? [] : {};
this[0].push(source);
this[1].push(target);
if (isArray(source)) {
source.forEach(function (value, key) {
target[key] = copyItem.call(this, value, key);
}, this);
ancestors.push(value);
ancestorsCopy.push(copy);
if (mode === "object") {
forEach(value, function (item, key) {
copy[key] = copyValue(item, ancestors, ancestorsCopy);
});
} else {
forEach(
source,
function (value, key) {
target[key] = copyItem.call(this, value, key);
},
this
);
value.forEach(function (item, index) {
copy[index] = copyValue(item, ancestors, ancestorsCopy);
});
}
return target;
ancestors.pop();
ancestorsCopy.pop();

return copy;
};

module.exports = function (source) {
var obj = Object(ensureValue(source));
if (obj !== source) return obj;
return copy.call([[], []], obj);
return copyValue(obj, [], []);
};

0 comments on commit bba529a

Please sign in to comment.