11const ostr = Object . prototype . toString ;
22const 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
1015const 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
4854const 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 = {
6874const 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 ;
7785const 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+
130225module . exports = {
131- contains, clone, diff
226+ contains, clone, diff, intersect , assign
132227} ;
0 commit comments