Skip to content

Commit e45d88b

Browse files
committed
[Circular] and more methods
1 parent 8729ae3 commit e45d88b

File tree

2 files changed

+142
-34
lines changed

2 files changed

+142
-34
lines changed

diff.js

Lines changed: 112 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
const ostr = Object.prototype.toString;
22
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-
}
3+
const object_keys = (...objs) => objs
4+
.reduce((a, b) => a.concat(Object.keys(b)), [])
5+
.filter((k, i, kk) => kk.indexOf(k) === i)
6+
;
7+
8+
// const for_up_loop = (len, fn, i, up = 1) => {
9+
// up = Math.max(1, up);
10+
// for(; i < len; i += up){
11+
// fn(i, len);
12+
// }
13+
// }
914

1015
const TYPE = (a, b) => {
1116
let n = tname(a);
@@ -41,22 +46,23 @@ const contains = (a, b, trap = []) => {
4146
if(t === '*' || !(t in CONTAINS)){
4247
return a === b;
4348
} else {
49+
trap.push(b);
4450
return CONTAINS[t](a, b, trap)
4551
}
4652
};
4753

4854
const CLONE = {
4955
'Array': (v, trap) => {
5056
if(trap.indexOf(v) > -1){
51-
return [ ...v ];
57+
return v;
5258
} else {
5359
trap.push(v);
5460
return v.map(vv => clone(vv, trap));
5561
}
5662
},
5763
'Object': (v, trap) => {
5864
if(trap.indexOf(v) > -1){
59-
return { ...v };
65+
return v;
6066
} else {
6167
trap.push(v);
6268
let o = {};
@@ -68,34 +74,41 @@ const CLONE = {
6874
const clone = (v, trap = []) => {
6975
let t = tname(v);
7076
if(t in CLONE){
77+
trap.push(v);
7178
return CLONE[t](v, trap);
7279
}
7380
return v;
7481
};
7582

76-
const DIFF_NONE = Symbol('-diff-none-');
83+
// const DIFF_NONE = Symbol('-diff-none-');
84+
const DIFF_NONE = undefined;
7785
const DIFF = {
7886
'Array': (a, b, trap) => {
7987
if(trap.indexOf(b) > -1){
8088
return DIFF_NONE;
8189
}
8290
trap.push(b);
83-
let i = 0, len = Math.max(a.length, b.length), o = [], none = true;
91+
let i = 0, len = Math.max(a.length, b.length), o = Array(len), none = true;
8492
for(; i < len; i++){
85-
o.push(diff(a[i], b[i], trap))
93+
let r = diff(a[i], b[i], trap);
94+
if(r !== DIFF_NONE){
95+
none = false;
96+
o[i] = r;
97+
}
98+
// o.push(r)
8699
};
87-
while(o[o.length - 1] === DIFF_NONE){
88-
o.pop();
89-
}
90-
return o.length > 0 ? o : DIFF_NONE;
100+
// while(o[o.length - 1] === DIFF_NONE){
101+
// o.pop();
102+
// }
103+
return none ? DIFF_NONE : o;
91104
},
92105
'Object': (a, b, trap) => {
93106
if(trap.indexOf(b) > -1){
94107
return DIFF_NONE;
95108
}
96109
trap.push(b);
97110
let o = {}, none = true;
98-
let keys = [...Object.keys(a), ...Object.keys(b)].filter((k, i, kk) => kk.indexOf(k) === i);
111+
let keys = object_keys(a, b);
99112
keys.forEach(i => {
100113
if(!contains(a[i], b[i])){
101114
let r = diff(a[i], b[i], trap);
@@ -127,6 +140,88 @@ const diff = (a, b, trap = []) => {
127140
return r;
128141
}
129142

143+
const INTERSECT = {
144+
'Array': (a, b, trap) => {
145+
if(trap.indexOf(b) > -1){
146+
return b;
147+
}
148+
trap.push(b);
149+
let _a = clone(a);
150+
b.forEach((v, i) => intersect(_a[i], v, trap));
151+
return _a;
152+
},
153+
'Object': (a, b, trap) => {
154+
if(trap.indexOf(b) > -1){
155+
return b;
156+
}
157+
trap.push(b);
158+
let o = {};
159+
for(let i in b){
160+
o[i] = intersect(a[i], b[i], trap);
161+
}
162+
return o;
163+
}
164+
};
165+
166+
const intersect = (a, b, trap = []) => {
167+
168+
let _b = diff(a, b);
169+
if(_b === DIFF_NONE){
170+
return DIFF_NONE;
171+
}
172+
let t = TYPE(a, _b);
173+
if(t === '*' || !(t in INTERSECT)){
174+
return _b;
175+
} else {
176+
return INTERSECT[t](a, _b, trap)
177+
}
178+
}
179+
180+
const ASSIGN = {
181+
'Array': (a, b, trap) => {
182+
if(trap.indexOf(b) > -1){
183+
return b;
184+
}
185+
trap.push(b);
186+
for(let i = 0, len = Math.max(a.length, b.length); i < len; i++){
187+
a[i] = assign2(a[i], b[i], trap);
188+
}
189+
return a;
190+
},
191+
'Object': (a, b, trap) => {
192+
if(trap.indexOf(b) > -1){
193+
return b;
194+
}
195+
trap.push(b);
196+
object_keys(a, b).forEach(i => a[i] = assign2(a[i], b[i], trap));
197+
return a;
198+
}
199+
};
200+
201+
const assign2 = (a, b, trap = []) => {
202+
if(b === DIFF_NONE || typeof(b) === 'undefined'){
203+
return a;
204+
}
205+
let t = TYPE(a, b);
206+
if(t === '*' || !(t in ASSIGN)){
207+
return clone(b);
208+
} else {
209+
trap.push(b);
210+
return ASSIGN[t](a, b, trap)
211+
}
212+
};
213+
214+
const assign = (a, ...args) => {
215+
if(args.length < 1){
216+
return a;
217+
} else {
218+
let trap = [];
219+
return args.reduce((A, B) => {
220+
return assign2(A, B, trap)
221+
}, a);
222+
}
223+
}
224+
130225
module.exports = {
131-
contains, clone, diff
226+
contains, clone, diff, intersect, assign
132227
};

test.js

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
1-
const { diff, clone } = require('./diff');
1+
const { diff, clone, intersect, assign } = require('./diff');
22

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] } };
3+
let a = { a: 1, b: 2 };
114
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;
5+
let b = { a: 1, b: 3 };
156
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))
7+
console.log('clone', clone(a));
8+
console.log('clone', clone(b));
9+
10+
console.log('diff', diff(a, b));
11+
console.log('diff', diff([1,2,3], [1,3,3,7]));
12+
console.log('diff', diff({a:1,b:2}, {a:1,b:3}));
13+
console.log('diff', diff({a:1,b:2, c: [1,2,3, { a: 111, b: 222 },4]}, {a:1,b:3, c: [2,2,3, { a: 111, c: 333 },4,5]}));
14+
15+
console.log('intersect', intersect(a, b));
16+
console.log('intersect', intersect([1,2,3], [1,3,3,7]));
17+
console.log('intersect', intersect({a:1,b:2}, {a:1,b:3}));
18+
console.log('intersect', intersect({a:1,b:2, c: [1,2,3, { a: 111, b: 222 },4]}, {a:1,b:3, c: [2,2,3, { a: 111, c: 333 },4,5]}));
19+
20+
console.log('assign', assign([1,2,3], [1,3,3,7]));
21+
console.log('assign', assign({a:1,b:2}, {a:1,b:3}));
22+
console.log('assign', assign({a:1,b:2, c: [1,2,3, { a: 111, b: 222 },4]}, {a:1,b:3, c: [2,2,3, { a: 111, c: 333 },4,5]}));
23+
console.log('assign', assign(a, b, a, b));
24+
25+
26+
// let aa = { a: 1 };
27+
// aa.z = aa;
28+
// let bb = assign(aa, { b: 2, d: [1,2,3] }, { b: 3, c: 4, d: [-11,12] });
29+
30+
// console.log(bb);
31+
// console.log(aa)
32+
// console.log(aa === bb);
33+

0 commit comments

Comments
 (0)