配列から、重複した配列を削除する方法はありますか。
質問:
次のような複数の配列からなる配列があります。
#(#(1, 5), #(6, 10), #(6, 10), #(14, 18), #(14, 18))
どのようにすれば、重複した配列 (この場合、2 番目と 3 番目、4 番目と 5 番目) を検索して取り除くことができるでしょうか。
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
|