リストと配列が等しいかどうかを確認しますF#
リストと配列を比較して、それらが等しいかどうかを確認しようとしています。リストlist = [1;2;3;4]
と配列があるとしましょうar = [|1;2;3;4|]
。true
等しい場合と等しくfalse
ない場合、関数は戻る必要があります。私はこのようにしました:
let list = [1;2;3;4]
let ar = [|1;2;3;4|]
let list' = Array.toList ar
(list = list')
つまり、基本的に私が行っているのは、2つのリストを変換して比較することです。私の質問は、これを行う他の方法があるということです。つまり、リストと配列の間で単純に変換するのではなく、ライブラリ関数に完全に依存しないのです。
回答
リストと配列(および他のほとんどのコレクション)の両方がseq<'a>
(IEnumerable<T>
.NET用語で)インターフェイスを実装しているという事実を利用できるため、Seq
変換せずにモジュールから関数にそれらを渡すことができます。これはインターフェイスを使用しているだけなので、オーバーヘッドはありません。
2つのシーケンスが同じであるかどうかをチェックするために私が考えることができる最も簡単な関数はforall2
、です。これは、2つのシーケンスを取り、述語が要素に対してペアで保持されていることをチェックします。この場合、述語は(fun a b -> a = b)
次のように省略できる単なる同等性テストです(=)
。
let list = [1;2;3;4]
let ar = [|1;2;3;4|]
Seq.forall2 (=) list ar
これを行う方法はたくさんあります。これは、要素をペアごとに比較するものです。
if list.Length = ar.Length then
Seq.zip list ar
|> Seq.forall (fun (a, b) -> a = b)
else false
F#ドキュメントによると:
Seq.compareWith関数を使用して、2つのシーケンスを比較します。この関数は、連続する要素を順番に比較し、最初の等しくないペアに遭遇すると停止します。追加の要素は比較に寄与しません。
あなたの場合、どちらがワンライナーになりますか:
0 = Seq.compareWith (Comparer<_>.Default) list ar
コンパイルされるかどうかを確認しませんでした。Comparer.Defaultを使用してプリミティブを比較します。そうでない場合、複雑なカスタムタイプの場合は、独自のタイプを提供する必要があります。
Linqで;
Enumerable.SequenceEqual (list, ar)
基づいて、この
let l = [1;2;3;4]
let a = [|1;2;3;4|]
let result = Seq.compareWith Operators.compare l a