配列から、重複した配列を削除する方法はありますか。

質問:

次のような複数の配列からなる配列があります。

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

どのようにすれば、重複した配列(この場合は、インデックス2 と 3 のアイテム(#(6,10))、および 4 と 5 のアイテム(#(14,18))) を検索して取り除くことができるでしょうか。

findItem を使用した場合、最初のインスタンスだけが返され、以降の検索が行われません。また、「for」ループをネストにして最初の数値と 2 番目の数値を比較しようとしましたが、考えている処理を行うようには設定できません。主に、配列をループで処理するときに、配列から項目を削除すると問題が起きてしまうようです。

回答:

デバッグ用の出力を追加したロング バージョンを示します。 これを見ればどのように処理されているかがわかります。

ループ処理を行っている配列から要素を削除するときに、必ず後方からカウントすることが重要になります。このようにしないと、要素が削除されたことより、配列項目の番号が更新されるため、ループが混乱してしまいます。

ロング バージョン:

    (
    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
    )

結果

    "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

コメント付きのコンパクト バージョン:

    (
    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
    )

結果:

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