スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#によるLinq to Obj入門 (12) All Any

まずはALLからです。シグネチャーをしらべてみると
 
> Enumerable.All;;
val it : seq<'a> * Func<'a,bool> -> bool = <fun:clo@7-1>
 
であり、引数のタプルの第二要素として各要素が条件を満たしているかどうかをテストする関数。
を渡します。(ちなみにこのような真か偽かを返す関数をpredicate(述語)といいます。)
 
predicateをfとする時、すべての要素eについてf e が真になるときAllは真を返し、それ以外の場合に偽を返します。
 
> Enumerable.All (seq[1;2;3],(fun x -> x > 0));;
val it : bool = true
 
> Enumerable.All (seq[1;2;3],(fun x -> x > 1));;
val it : bool = false
 
空のシークエンスに対しては常に真を返します。
 
> Enumerable.All (seq[],(fun x -> x >1));;
val it : bool = true
 
引数のタプルの第一成分に対するインスタンスメソッドとしても定義されています。
 
> (seq[1;2;3]).All (fun x -> x >0);;
val it : bool = true
 
Seqモジュールではforallが対応します。
 
> Seq.forall (fun x ->  x > 0) (seq[1;2;3]);;
val it : bool = true
 
またSeqモジュールにはforall2というメソッドがあります。シグネチャーを調べてみると
 
> Seq.forall2;;
val it : (('a -> 'b -> bool) -> seq<'a> -> seq<'b> -> bool) = <fun:clo@4>
 
であり、2つのシーケンスから取り出したすべての要素ペアが、指定された述語を満たすかどうかをテストします。(一方のシーケンスが他方より短い場合、長い方のシーケンスの残りの要素は無視されます。)
 
要素ペアを取り出して、ペアの和がすべて5より小さいかを調べてみます。
 
> Seq.forall2 (fun x y ->  x + y <5) (seq[1;2;3]) (seq[1;2;0]);;
val it : bool = true
 
> Seq.forall2 (fun x y ->  x + y <5) (seq[1;2;3]) (seq[1;2;3]);;
val it : bool = false
 
ついでに3つ版を定義してみます。
 
> let myForall3 f (source1: seq<_>) (source2: seq<_>) (source3: seq<_>) = 
      use e1 = source1.GetEnumerator()
      use e2 = source2.GetEnumerator()
      use e3 = source3.GetEnumerator()
 
      let rec loop res =
         if not (e1.MoveNext() &&  e2.MoveNext() && e3.MoveNext()) then //どれかは進めない
              res //trueでも同じ
         else
            if f e1.Current e2.Current e3.Current = false then    
              false
            else
               loop true  
 
      loop true;;
 
val myForall3 :
  ('a -> 'b -> 'b -> bool) -> seq<'a> -> seq<'b> -> seq<'c> -> bool
 
使用例
 
> myForall3 (fun x y z -> x + y + z < 10) (seq[1;1]) (seq[3;2]) (seq[3;5]);;
val it : bool = true
 
> myForall3 (fun x y z -> x + y + z < 10) (seq[1;4]) (seq[3;2]) (seq[3;5]);;
val it : bool = false
 
> myForall3 (fun x y z -> x + y + z < 10) (seq[1]) (seq[3;2]) (seq[3;5]);;
val it : bool = true
 
 
次にAnyです。シグネチャーは
 
static member Any : 
        source:IEnumerable<'TSource> * 
        predicate:Func<'TSource, bool> -> bool 
 
で、Allに対してこちらは、すくなくとも一つの要素eについて、predicate e が真の時に真を返します。
 
> Enumerable.Any (seq[1;2;3],(fun x -> x > 2));;
val it : bool = true
 
> Enumerable.Any (seq[1;2;3],(fun x -> x > 4));;
val it : bool = false
 
空のシークエンスに対しては常に偽を返します。
 
> Enumerable.All (seq[],(fun x -> x >1));;
val it : bool = true
 
インスタンスメソッドについてはAllと同様です。
 
SeqモジュールではSeq.existが対応します。
 
> Seq.exists (fun x -> x > 2) (seq[1;2;3]);;
val it : bool = true
 
> Seq.exists (fun x -> x > 3) (seq[1;2;3]);;
val it : bool = false
 
またSeq.exist2も定義されています。
 
> Seq.exists2 (fun x y ->  x + y <3) (seq[1;2;3]) (seq[1;2;3]);;
val it : bool = true
 
> Seq.exists2 (fun x y ->  x + y < 2) (seq[1;2;3]) (seq[1;2;3]);;
val it : bool = false
 
 
Anyはオーバーロードされていて、次のようなシグネチャーのものがあります。
 
static member Any : 
        source:IEnumerable<'TSource> -> bool 
        
これは、シークエンスが空のときは偽を返し、そうでないときは真を返します。
 
> Enumerable.Any (seq[1;2]);;
val it : bool = true
 
> Enumerable.Any (seq[]);;
val it : bool = false
 
つまりisNotEmptyという意味合いになります。
 
SeqモジュールではSeq.isEmptyが対応します。
 
> Seq.isEmpty (seq[1]);;
val it : bool = false
 
> Seq.isEmpty (seq[]);;
val it : bool = true
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。