arraysrubysketchup

Sketchup: Ruby array return matching and non matching sub arrays with specific element


I have 2 arrays that look like this and I'd like to find the matching and non matching Point3d values.

a = [['xxx', [0.203125, 0.203125, 0.0], 
      Point3d(12, 1.25984, -0.275591), nil], 
     ['eee', [0.203125, 0.203125, 0.0], 
      Point3d(12, 20.0995, -0.275591), nil]]

b = [['aaa', [0.203125, 0.203125, 0.0], 
      Point3d(10, 1.25984, -0.275591), nil], 
     ['sss', [0.203125, 0.203125, 0.0], 
      Point3d(10, 20.0995, -0.275591), nil], 
     ['www', [0.203125, 0.203125, 0.0], 
      Point3d(12, 1.25984, -0.275591), nil], 
     ['nnn', [0.203125, 0.203125, 0.0], 
      Point3d(12, 20.0995, -0.275591), nil]]

should return 2 arrays, one with matching Point3ds...

result_match = [['xxx', [0.203125, 0.203125, 0.0], 
                 Point3d(12, 1.25984, -0.275591), nil], 
                ['eee', [0.203125, 0.203125, 0.0], 
                 Point3d(12, 20.0995, -0.275591), nil]]

and non matching Point3ds...

result_non_match = [['aaa', [0.203125, 0.203125, 0.0], 
                     Point3d(10, 1.25984, -0.275591), nil], 
                    ['sss', [0.203125, 0.203125, 0.0], 
                     Point3d(10, 20.0995, -0.275591), nil]]

I've searched and tried the results that show up but they don't seem to work since they all work with arrays and not point3ds. The closest I found is this but I can't get that to work...

samepoint = a.map(&:to_a) & b.map(&:to_a)

Solution

  • You want to create sets of points.

    a_set = a.map { |x| x[2] }.to_set
    b_set = b.map { |x| x[2] }.to_set
    

    Now you can find points which occur in both sets using a set intersection &, and the difference using ^.

    intersect = a_set & b_set
    diff = a_set ^ b_set
    

    Having gotten these values, need only filter your arrays to match for those values.

    matches = (a + b).select { |x| intersect.include?(x[2]) }