Skip to content

Commit 5c2acef

Browse files
committed
first commit
0 parents  commit 5c2acef

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# diff
2+
diff

diff.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
const ostr = Object.prototype.toString;
2+
const tname = v => ostr.call(v).slice(8, -1);
3+
const isEmptyObj = v => {
4+
for(let p in v){
5+
return false;
6+
}
7+
return true;
8+
}
9+
10+
const TYPE = (a, b) => {
11+
let nameA = tname(a), nameB = tname(b);
12+
return nameA === nameB ? nameA : '*';
13+
};
14+
15+
const CONTAINS = {
16+
'Array': (a, b, trap) => {
17+
if(trap.indexOf(b) > -1){
18+
return true;
19+
}
20+
trap.push(b);
21+
if(b.length <= a.length){
22+
return b.every((vb, i) => contains(a[i], vb, trap))
23+
} else {
24+
return false;
25+
}
26+
},
27+
'Object': (a, b, trap) => {
28+
if(trap.indexOf(b) > -1){
29+
return true;
30+
}
31+
trap.push(b);
32+
let bKeys = Object.keys(b);
33+
if(bKeys.some(k => !(k in a))){
34+
return false;
35+
}
36+
return bKeys.every(i => contains(a[i], b[i], trap))
37+
}
38+
};
39+
const contains = (a, b, trap = []) => {
40+
let t = TYPE(a, b);
41+
if(t === '*' || !(t in CONTAINS)){
42+
return a === b;
43+
} else {
44+
return CONTAINS[t](a, b, trap)
45+
}
46+
};
47+
48+
const CLONE = {
49+
'Array': (v, trap) => {
50+
if(trap.indexOf(v) > -1){
51+
return [ ...v ];
52+
} else {
53+
trap.push(v);
54+
return v.map(vv => clone(vv, trap));
55+
}
56+
},
57+
'Object': (v, trap) => {
58+
if(trap.indexOf(v) > -1){
59+
return { ...v };
60+
} else {
61+
trap.push(v);
62+
let o = {};
63+
Object.keys(v).forEach(key => o[key] = clone(v[key], trap));
64+
return o;
65+
}
66+
}
67+
};
68+
const clone = (v, trap = []) => {
69+
let t = tname(v);
70+
if(t in CLONE){
71+
return CLONE[t](v, trap);
72+
}
73+
return v;
74+
};
75+
76+
const DIFF_NONE = Symbol('-diff-none-');
77+
const DIFF = {
78+
'Array': (a, b, trap) => {
79+
if(trap.indexOf(b) > -1){
80+
return DIFF_NONE;
81+
}
82+
trap.push(b);
83+
let i = 0, len = Math.max(a.length, b.length), o = [], none = true;
84+
for(; i < len; i++){
85+
o.push(diff(a[i], b[i], trap))
86+
};
87+
while(o[o.length - 1] === DIFF_NONE){
88+
o.pop();
89+
}
90+
return o.length > 0 ? o : DIFF_NONE;
91+
},
92+
'Object': (a, b, trap) => {
93+
if(trap.indexOf(b) > -1){
94+
return DIFF_NONE;
95+
}
96+
trap.push(b);
97+
let o = {}, none = true;
98+
let keys = [...Object.keys(a), ...Object.keys(b)].filter((k, i, kk) => kk.indexOf(k) === i);
99+
keys.forEach(i => {
100+
if(!contains(a[i], b[i])){
101+
let r = diff(a[i], b[i], trap);
102+
if(r !== DIFF_NONE){
103+
none = false;
104+
o[i] = r;
105+
}
106+
}
107+
});
108+
return none ? DIFF_NONE : o;
109+
}
110+
};
111+
const diff = (a, b, trap = []) => {
112+
if(typeof(a) === 'undefined'){
113+
if(typeof(b) === 'undefined'){
114+
return DIFF_NONE;
115+
} else {
116+
return clone(b);
117+
}
118+
} else if(typeof(b) === 'undefined'){
119+
return DIFF_NONE;
120+
}
121+
let t = TYPE(a, b), r;
122+
if(t === '*' || !(t in DIFF)){
123+
r = a === b ? DIFF_NONE : b;
124+
} else {
125+
r = DIFF[t](a, b, trap);
126+
}
127+
return r;
128+
}
129+
130+
module.exports = {
131+
contains, clone, diff
132+
};

test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const { diff, clone } = require('./diff');
2+
3+
const obj = [1,2, {'a': [{bbb:3}, [1,{aaa:2},2,3,]]}];
4+
const _obj = clone(obj);
5+
// obj.push(3)
6+
obj.push(4)
7+
_obj.push(3)
8+
// console.log(obj === _obj, contains(obj, _obj), JSON.stringify(_obj), JSON.stringify(obj))
9+
10+
let a = { a: 1, b: 2, c: { a: 1, b: [1,2,3] } };
11+
a.z = a;
12+
let b = { a: 1, b: 2, c: { a: 1, b: [1,2,4] } };
13+
let c = { a: 1, b: 2, c: { a: 1, b: [1,2,3] } };
14+
c.z = b;
15+
b.z = b;
16+
// console.log(clone(a))
17+
console.log(diff([1,2,3], [1,3,3]))
18+
console.log(diff({ a: [1,2,3] }, { a: [1,2,3] }))
19+
console.log(diff(a, b))
20+
console.log(diff(obj, _obj))

0 commit comments

Comments
 (0)