@@ -256,7 +256,9 @@ func (ns *Namespace) In(l interface{}, v interface{}) bool {
256256 }
257257 default :
258258 if isNumber (vv .Kind ()) && isNumber (lvv .Kind ()) {
259- if numberToFloat (vv ) == numberToFloat (lvv ) {
259+ f1 , err1 := numberToFloat (vv )
260+ f2 , err2 := numberToFloat (lvv )
261+ if err1 == nil && err2 == nil && f1 == f2 {
260262 return true
261263 }
262264 }
@@ -277,69 +279,24 @@ func (ns *Namespace) Intersect(l1, l2 interface{}) (interface{}, error) {
277279 return make ([]interface {}, 0 ), nil
278280 }
279281
282+ var ins * intersector
283+
280284 l1v := reflect .ValueOf (l1 )
281285 l2v := reflect .ValueOf (l2 )
282286
283287 switch l1v .Kind () {
284288 case reflect .Array , reflect .Slice :
289+ ins = & intersector {r : reflect .MakeSlice (l1v .Type (), 0 , 0 ), seen : make (map [interface {}]bool )}
285290 switch l2v .Kind () {
286291 case reflect .Array , reflect .Slice :
287- r := reflect .MakeSlice (l1v .Type (), 0 , 0 )
288292 for i := 0 ; i < l1v .Len (); i ++ {
289293 l1vv := l1v .Index (i )
290294 for j := 0 ; j < l2v .Len (); j ++ {
291295 l2vv := l2v .Index (j )
292- switch l1vv .Kind () {
293- case reflect .String :
294- l2t , err := toString (l2vv )
295- if err == nil && l1vv .String () == l2t && ! ns .In (r .Interface (), l1vv .Interface ()) {
296- r = reflect .Append (r , l1vv )
297- }
298- case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
299- l2t , err := toInt (l2vv )
300- if err == nil && l1vv .Int () == l2t && ! ns .In (r .Interface (), l1vv .Interface ()) {
301- r = reflect .Append (r , l1vv )
302- }
303- case reflect .Float32 , reflect .Float64 :
304- l2t , err := toFloat (l2vv )
305- if err == nil && l1vv .Float () == l2t && ! ns .In (r .Interface (), l1vv .Interface ()) {
306- r = reflect .Append (r , l1vv )
307- }
308- case reflect .Interface :
309- switch l1vvActual := l1vv .Interface ().(type ) {
310- case string :
311- switch l2vvActual := l2vv .Interface ().(type ) {
312- case string :
313- if l1vvActual == l2vvActual && ! ns .In (r .Interface (), l1vvActual ) {
314- r = reflect .Append (r , l1vv )
315- }
316- }
317- case int , int8 , int16 , int32 , int64 :
318- switch l2vvActual := l2vv .Interface ().(type ) {
319- case int , int8 , int16 , int32 , int64 :
320- if l1vvActual == l2vvActual && ! ns .In (r .Interface (), l1vvActual ) {
321- r = reflect .Append (r , l1vv )
322- }
323- }
324- case uint , uint8 , uint16 , uint32 , uint64 :
325- switch l2vvActual := l2vv .Interface ().(type ) {
326- case uint , uint8 , uint16 , uint32 , uint64 :
327- if l1vvActual == l2vvActual && ! ns .In (r .Interface (), l1vvActual ) {
328- r = reflect .Append (r , l1vv )
329- }
330- }
331- case float32 , float64 :
332- switch l2vvActual := l2vv .Interface ().(type ) {
333- case float32 , float64 :
334- if l1vvActual == l2vvActual && ! ns .In (r .Interface (), l1vvActual ) {
335- r = reflect .Append (r , l1vv )
336- }
337- }
338- }
339- }
296+ ins .handleValuePair (l1vv , l2vv )
340297 }
341298 }
342- return r .Interface (), nil
299+ return ins . r .Interface (), nil
343300 default :
344301 return nil , errors .New ("can't iterate over " + reflect .ValueOf (l2 ).Type ().String ())
345302 }
@@ -531,6 +488,41 @@ func (ns *Namespace) Slice(args ...interface{}) []interface{} {
531488 return args
532489}
533490
491+ type intersector struct {
492+ r reflect.Value
493+ seen map [interface {}]bool
494+ }
495+
496+ func (i * intersector ) appendIfNotSeen (v reflect.Value ) {
497+ vi := v .Interface ()
498+ if ! i .seen [vi ] {
499+ i .r = reflect .Append (i .r , v )
500+ i .seen [vi ] = true
501+ }
502+ }
503+
504+ func (ins * intersector ) handleValuePair (l1vv , l2vv reflect.Value ) {
505+ switch kind := l1vv .Kind (); {
506+ case kind == reflect .String :
507+ l2t , err := toString (l2vv )
508+ if err == nil && l1vv .String () == l2t {
509+ ins .appendIfNotSeen (l1vv )
510+ }
511+ case isNumber (kind ):
512+ f1 , err1 := numberToFloat (l1vv )
513+ f2 , err2 := numberToFloat (l2vv )
514+ if err1 == nil && err2 == nil && f1 == f2 {
515+ ins .appendIfNotSeen (l1vv )
516+ }
517+ case kind == reflect .Ptr , kind == reflect .Struct :
518+ if l1vv .Interface () == l2vv .Interface () {
519+ ins .appendIfNotSeen (l1vv )
520+ }
521+ case kind == reflect .Interface :
522+ ins .handleValuePair (reflect .ValueOf (l1vv .Interface ()), l2vv )
523+ }
524+ }
525+
534526// Union returns the union of the given sets, l1 and l2. l1 and
535527// l2 must be of the same type and may be either arrays or slices.
536528// If l1 and l2 aren't of the same type then l1 will be returned.
@@ -547,105 +539,54 @@ func (ns *Namespace) Union(l1, l2 interface{}) (interface{}, error) {
547539 l1v := reflect .ValueOf (l1 )
548540 l2v := reflect .ValueOf (l2 )
549541
542+ var ins * intersector
543+
550544 switch l1v .Kind () {
551545 case reflect .Array , reflect .Slice :
552546 switch l2v .Kind () {
553547 case reflect .Array , reflect .Slice :
554- r := reflect .MakeSlice (l1v .Type (), 0 , 0 )
548+ ins = & intersector { r : reflect .MakeSlice (l1v .Type (), 0 , 0 ), seen : make ( map [ interface {}] bool )}
555549
556550 if l1v .Type () != l2v .Type () &&
557551 l1v .Type ().Elem ().Kind () != reflect .Interface &&
558552 l2v .Type ().Elem ().Kind () != reflect .Interface {
559- return r .Interface (), nil
553+ return ins . r .Interface (), nil
560554 }
561555
562- var l1vv reflect.Value
556+ var (
557+ l1vv reflect.Value
558+ isNil bool
559+ )
560+
563561 for i := 0 ; i < l1v .Len (); i ++ {
564- l1vv = l1v .Index (i )
565- if ! ns . In ( r . Interface (), l1vv . Interface ()) {
566- r = reflect . Append ( r , l1vv )
562+ l1vv , isNil = indirectInterface ( l1v .Index (i ) )
563+ if ! isNil {
564+ ins . appendIfNotSeen ( l1vv )
567565 }
568566 }
569567
570568 for j := 0 ; j < l2v .Len (); j ++ {
571569 l2vv := l2v .Index (j )
572570
573- switch l1vv .Kind () {
574- case reflect .String :
571+ switch kind := l1vv .Kind (); {
572+ case kind == reflect .String :
575573 l2t , err := toString (l2vv )
576- if err == nil && ! ns .In (r .Interface (), l2t ) {
577- r = reflect .Append (r , reflect .ValueOf (l2t ))
578- }
579- case reflect .Int :
580- l2t , err := toInt (l2vv )
581- if err == nil && ! ns .In (r .Interface (), l2t ) {
582- r = reflect .Append (r , reflect .ValueOf (int (l2t )))
583- }
584- case reflect .Int8 :
585- l2t , err := toInt (l2vv )
586- if err == nil && ! ns .In (r .Interface (), l2t ) {
587- r = reflect .Append (r , reflect .ValueOf (int8 (l2t )))
588- }
589- case reflect .Int16 :
590- l2t , err := toInt (l2vv )
591- if err == nil && ! ns .In (r .Interface (), l2t ) {
592- r = reflect .Append (r , reflect .ValueOf (int16 (l2t )))
574+ if err == nil {
575+ ins .appendIfNotSeen (reflect .ValueOf (l2t ))
593576 }
594- case reflect .Int32 :
595- l2t , err := toInt (l2vv )
596- if err == nil && ! ns .In (r .Interface (), l2t ) {
597- r = reflect .Append (r , reflect .ValueOf (int32 (l2t )))
598- }
599- case reflect .Int64 :
600- l2t , err := toInt (l2vv )
601- if err == nil && ! ns .In (r .Interface (), l2t ) {
602- r = reflect .Append (r , reflect .ValueOf (l2t ))
603- }
604- case reflect .Float32 :
605- l2t , err := toFloat (l2vv )
606- if err == nil && ! ns .In (r .Interface (), float32 (l2t )) {
607- r = reflect .Append (r , reflect .ValueOf (float32 (l2t )))
608- }
609- case reflect .Float64 :
610- l2t , err := toFloat (l2vv )
611- if err == nil && ! ns .In (r .Interface (), l2t ) {
612- r = reflect .Append (r , reflect .ValueOf (l2t ))
613- }
614- case reflect .Interface :
615- switch l1vv .Interface ().(type ) {
616- case string :
617- switch l2vvActual := l2vv .Interface ().(type ) {
618- case string :
619- if ! ns .In (r .Interface (), l2vvActual ) {
620- r = reflect .Append (r , l2vv )
621- }
622- }
623- case int , int8 , int16 , int32 , int64 :
624- switch l2vvActual := l2vv .Interface ().(type ) {
625- case int , int8 , int16 , int32 , int64 :
626- if ! ns .In (r .Interface (), l2vvActual ) {
627- r = reflect .Append (r , l2vv )
628- }
629- }
630- case uint , uint8 , uint16 , uint32 , uint64 :
631- switch l2vvActual := l2vv .Interface ().(type ) {
632- case uint , uint8 , uint16 , uint32 , uint64 :
633- if ! ns .In (r .Interface (), l2vvActual ) {
634- r = reflect .Append (r , l2vv )
635- }
636- }
637- case float32 , float64 :
638- switch l2vvActual := l2vv .Interface ().(type ) {
639- case float32 , float64 :
640- if ! ns .In (r .Interface (), l2vvActual ) {
641- r = reflect .Append (r , l2vv )
642- }
643- }
577+ case isNumber (kind ):
578+ var err error
579+ l2vv , err = convertNumber (l2vv , kind )
580+ if err == nil {
581+ ins .appendIfNotSeen (l2vv )
644582 }
583+ case kind == reflect .Interface , kind == reflect .Struct , kind == reflect .Ptr :
584+ ins .appendIfNotSeen (l2vv )
585+
645586 }
646587 }
647588
648- return r .Interface (), nil
589+ return ins . r .Interface (), nil
649590 default :
650591 return nil , errors .New ("can't iterate over " + reflect .ValueOf (l2 ).Type ().String ())
651592 }
0 commit comments