How do I remove duplicate arrays from an array?

A user asked

I have an array of arrays like this:

#(#(1, 5), #(6, 10), #(6, 10), #(14, 18), #(14, 18))

How can I search for, and get rid of, the duplicates, which in this case would be items at indices 2 & 3 (#(6,10)), and 4 & 5 (#(14,18)).

If I use find Item, it just returns the first instance and does not continue searching. I have also tried comparing the first and second numbers using nested 'for' loops, but I cannot set it up to work like I want. Mainly, there seems to be problems when deleting items from an array while it is going through a loop.

Answer

Here is a long version with some debug prints so you can see what is happening.

The key is to always count backwards when deleting elements from an array you are looping through. Otherwise, the loop gets confused as deleting elements renumbers the array items.

LONG VERSION

   (
       theArray = #(#(1, 5), #(6, 10), #(6, 10), #(14, 18), #(14, 18))
       print "Before:"
       print theArray
       fn compareSubArrays first second =
       (
           result = true
           if first.count != second.count then
               result = false
           else
               for i = 1 to first.count do
                   if first[i] != second[i] do result = false
           result
       )
       for i = 1 to theArray.count do
       (
           for j = theArray.count to (i + 1) by -1 do
           (
               format "Comparing %:% to %:% \n" i theArray[i] j theArray[j]
               test = (compareSubArrays theArray[i] theArray[j])
               print test
               if test do
               (
                   deleteItem theArray j
                   format "Deleting %\n" j
               )
           ) --end j loop
       ) --end i loop
       print "After:"
       print theArray
   )

RESULTS:

   "Before:"
   #(1, 5)
   #(6, 10)
   #(6, 10)
   #(14, 18)
   #(14, 18)
   Comparing 1:#(1, 5) to 5:#(14, 18)
   false
   Comparing 1:#(1, 5) to 4:#(14, 18)
   false
   Comparing 1:#(1, 5) to 3:#(6, 10)
   false
   Comparing 1:#(1, 5) to 2:#(6, 10)
   false
   Comparing 2:#(6, 10) to 5:#(14, 18)
   false
   Comparing 2:#(6, 10) to 4:#(14, 18)
   false
   Comparing 2:#(6, 10) to 3:#(6, 10)
   true
   Deleting 3
   Comparing 3:#(14, 18) to 4:#(14, 18)
   true
   Deleting 4
   "After:"
   #(1, 5)
   #(6, 10)
   #(14, 18)
   OK
   OK

COMPACT VERSION WITH COMMENTS:

   (
       theArray = #(#(1, 5), #(6, 10), #(6, 10), #(14, 18), #(14, 18))
       -- Function to compare the content of two arrays
       fn compareSubArrays first second =
       (
           result = true -- init. return value to true
           if first.count != second.count then -- if the count of the two subarrays is different,
               result = false -- return false
           else -- otherwise
               for i = 1 to first.count do -- go through all elements in the arrays
                   if first[i] != second[i] do result = false -- and see if two elements are different
           result -- return the result - true if identical, false if not
       )
       for i = 1 to theArray.count do -- go through all elements of the main array
           for j = theArray.count to (i + 1) by -1 do -- go backwards from the last to the current+1
               if compareSubArrays theArray[i] theArray[j] do
                   deleteItem theArray j -- if identical, delete the one with the higher index
       format "%\n" theArray -- print the result to the Listener
   )

RESULT:

   #(#(1, 5), #(6, 10), #(14, 18))
   OK
   OK