説明が2番目の例とあまり一致しません。 の値を最初にに置き換えたいとしましたが、2番目の例では、(3,"l")
をの最後のに置き換えました((3,"x")
ではなく(3,"f")
)。最後の複製に置き換えることははるかに簡単ですが、どちらも実行できます。
最後の複製で置き換えるには、明確なキーと値のペアのリストを更新して最終的なリストを表示します。この更新を行う関数を記述し、リスト上で、この更新機能を実行し、空のリストで始まる:
fun update (i,c) [] = [(i,c)]
| update (i,c) ((j,d)::records) =
if i = j then
(i,c)::records
else
(j,d) :: (update (i,c) records)
fun updateAll [] records = records
| updateAll ((i,c)::pairs) records = updateAll pairs (update (i,c) records)
fun removeVarDuplicates pairs = updateAll pairs [];
あなたの二つの例のために予想されるように、この機能は動作します。
最後に、最初にの複製値が保持されるアプローチがあります。これを行うには、値が更新されたかどうかを示すBooleanフラグを追加します。初めて更新する - フラグを設定します。最終的な結果にフラグを剥ぎ:
fun update (i,c) [] = [(i,c,false)]
| update (i,c) ((j,d,t)::triples) =
if i = j then
if t then (j,d,t) :: triples else (j,c,true)::triples
else
(j,d,t) :: (update (i,c) triples)
fun updateAll [] triples = triples
| updateAll ((i,c)::pairs) triples = updateAll pairs (update (i,c) triples)
fun removeVarDuplicates pairs =
let
val triples = updateAll pairs []
in
map (fn (x,y,_) => (x,y)) triples
end;
をこれはあなたの第二の例に対して実行された場合:
最初の重複キー
"x"
の最初の値を第2の重複のための値ではなく保持され
- val mylist = [(1,"h"),(3,"l"),(45,"j"),(3, "x"), (3, "f")];
val mylist = [(1,"h"),(3,"l"),(45,"j"),(3,"x"),(3,"f")] : (int * string) list
- removeVarDuplicates mylist;
val it = [(1,"h"),(3,"x"),(45,"j")] : (int * string) list
キー。
キーと値を含む深刻な作業については、SML/NJのhash tableなどの別のデータ構造の使用を検討する必要があります。私が上で与えたコードは、恐ろしく非効率的であり、最終結果はO(n)
ルックアップのデータ構造です。
OPで不明な点がありまして申し訳ありませんが、私はあまりにも問題を言い換えることができます。あなたが与えた2番目のコード例では、 '(3、" f ")' – rshah
@rshahで終わるはずのリストは '(3、" x ")'で終わります。 s、 "f") 'である。私が言ったように、あなたに質問を読むための2つの方法があったので、私は両方に答えました。私は最初の解釈(あなたの例に基づいて)が意図されたものだと思ったが、最後の重複ではなく最初のものを保持する方法を考えるのは楽しいと思った。 –