プログラミング言語の比較(リスト内包表記)
リスト内包表記は、既存のリストに基づいてリストを作成するために一部のプログラミング言語で利用可能な構文構造です。これは、マップ関数やフィルター関数とは異なり、数学的な集合構築記法(集合内包表記)の形式に従います。
リスト内包表記の例
ブー
0 から 10 までのすべてのダブルのリスト(除外)
doubles = [ i * 2 (iは範囲(10 )内)] リオデジャネイロに拠点を置く顧客の名前のリスト
rjCustomers = [ customer . State == "RJ"の場合、customers内の顧客の名前] C++
C++ では、 C++20std::viewsで導入された名前空間を使用できます。
std :: vectorを使用します。std :: ranges :: toを使用します。std :: views :: filterを使用します。std :: views :: transform を使用します。 vector < int > ns = std :: views :: iota ( 0 , 100 ) | filter ([]( int x ) -> bool { return x * x > 3 ; }) | transform ([]( int x ) -> int { return x * 2 ; }) | to < vector > (); C#
IEnumerable < int > ns = from x in Enumerable . Range ( 0 , 100 ) where x * x > 3 select x * 2 ; 前のコードは、ラムダ式を使用して記述された次のコードの構文糖です。
IEnumerable < int > ns = Enumerable . Range ( 0 , 100 ) . Where ( x => x * x > 3 ) . Select ( x => x * 2 ); セイロン
3 で割り切れる数値をフィルタリングする:
value divisibleBy3 = { for ( i in 0 .. 100 ) if ( i % 3 == 0 ) i }; // divisibleBy3 の型は Iterable<Integer> です 複数の「ジェネレータ」:
value triples = { for ( x in 0 .. 20 ) for ( y in x .. 20 ) for ( z in y .. 20 ) if ( x * x + y * y == z * z ) [ x , y , z ] }; // トリプルの型はIterable<Integer[3]>です クロージュア
無限の遅延シーケンス:
( for [x ( iterate inc 0 ) :when ( > ( * x x ) 3 ) ] ( * 2 x )) 複数のジェネレータを使用したリストの理解:
( for [x (範囲20 ) y (範囲20 ) z (範囲20 ) :when ( == ( + ( * x x ) ( * y y )) ( * z z )) ] [x y z] ) コーヒースクリプト
largeNumbers = (数値> 100の場合のリスト内の数値) コモンリスプ
loopリスト内包表記はマクロのキーワードで表現できますcollect。条件文はif次のように で表現されます。
( xを0から100までループします。 if ( > ( * x x ) 3 ) collect ( * 2 x )) コブラ
顧客の名前をリストします:
names = 顧客のcustに対して cust.nameを取得する 残高のある顧客を一覧表示します。
names = cust in customers where cust . balance > 0 残高のある顧客の名前をリストします。
names = cust in customers where cust . balance > 0 cust . nameを取得します 一般的な形式:
ENUMERABLE内のVAR について[条件付き条件]条件付き条件のVARについてEXPRを取得します 条件と式を変数名と列挙可能なオブジェクトの後に置くと、エディターと IDE で変数のメンバーの自動補完が提供されることに注意してください。
ダーツ
[ for ( var i in range ( 0 , 100 )) if ( i * i > 3 ) i * 2 ] var pyth = [ for ( var x in range ( 1 , 20 )) for ( var y in range ( x , 20 )) for ( var z in range ( y , 20 )) if ( x * x + y * y == z * z ) [ x , y , z ] ]; Iterable < int > range ( int start , int end ) => List . generate ( end - start , ( i ) => start + i ); エリクサー
x <- 0 .. 100 、x * x > 3の場合、x * 2を実行します。 アーラン
L =リスト: seq ( 0 , 100 )。S = [ 2 * X || X < - L , X * X > 3 ]。 F#
遅延評価されたシーケンス:
seq { xが0 .. 100 の場合、x * x > 3であれば2 * xを返す} または、浮動小数点値の場合
seq { xが0 . . . 100 の場合、x ** 2 . > 3 .の場合、2 . * xが返されます} リストと配列:
[ xが0 . . 100 の場合、x ** 2 . > 3 .なら2 . * xを返します] [| xが0 . . 100 の場合、x ** 2 . > 3 .なら2 . * xを返します|] リストの内包表記は、計算式と呼ばれるより大きな言語構成要素の一部です。
ハスケル
[ x * 2 | x <- [ 0 .. 99 ]、x * x > 3 ] 複数のジェネレータを使用したリストの理解の例:
pyth = [( x , y , z ) | x <- [ 1 .. 20 ]、y <- [ x .. 20 ]、z <- [ y .. 20 ]、x ^ 2 + y ^ 2 == z ^ 2 ] イオ
Range オブジェクトを使用すると、Io 言語は他の言語と同じくらい簡単にリストを作成できます。
範囲0から(100 )asList select (x 、x * x > 3 )map (* 2 ) ISLISP
リスト内包表記は特殊形式 で表現できますfor。条件文は で表現されますif。
( for (( x 0 ( + x 1 )) ( collect ())) (( >= x 100 ) (逆collect )) ( if ( > ( * x x ) 3 ) ( setq collect ( cons ( * x 2 ) collect )))) ジュリア
Julia は次の構文を使用した内包表記をサポートしています。
y = [ x ^ 2 + 1 ( xは1:10の範囲)] そして次のような多次元的な理解:
z = [( x - 5 ) ^ 2 + ( y - 5 ) ^ 2 (x = 0 : 10 、y = 0 : 10 ) 条件を追加することもできます:
v = [ 3 x ^ 2 + 2 y ^ 2 ( xが1の場合: 7 、 yが1の場合: 7 )x % y == 0 の場合] 角括弧を丸括弧に変更するだけで、ジェネレーターが作成されます。
g = ( 3 x ^ 2 + 2 y ^ 2 、xが1 : 7 、yが1 : 7 、 x % y == 0 の場合) ミスリル
s = [ 2*i (i は 1..100 の範囲、i*i > 3 ) ];
複数のジェネレータ:
pyth = [ (x,y,z)、x は 1..20 の範囲内、y は x..20 の範囲内、z は y..20 の範囲内、ただし x*x + y*y == z*z ];
ネメルル
$[ x * 2 | xは [ 0 .. 100 ]の範囲にあり 、x * x > 3 ] ニム
Nimは、sugar標準ライブラリモジュールにseq、set、table、objectの内包表記を組み込んでいます。[1]
輸入砂糖 let variable = collect ( newSeq ): for item in @[- 9 , 1 , 42 , 0 , - 1 , 9 ] : item + 1 変数== @[- 8 , 2 , 43 , 1 , 0 , 10 ]をアサートする 理解はコンパイル時に展開されるマクロとして実装されており、展開されたコードはexpandMacroコンパイラ オプションを使用して確認できます。
var collectResult = newSeq ( Natural ( 0 ))アイテム内のアイテム( @ [- 9 , 1 , 42 , 0 , - 1 , 9 ] ): add ( collectResult , item + 1 ) collectResult 内包表記はネスト可能で、複数行に渡ることもできます。
輸入砂糖 values = collect ( newSeq ): for val in [ 1 , 2 ] : collect ( newSeq ): for val2 in [ 3 , 4 ] : if ( val , val2 ) != ( 1 , 2 ): ( val , val2 ) assert values == @[@[ ( 1 , 3 ) , ( 1 , 4 ) ] , @[ ( 2 , 3 ), ( 2 , 4 ) ]] OCaml
OCamlはOCaml Batteriesを通じてリストの理解をサポートしています。[2]
パール
私の@s = map { 2 * $_ } grep { $_ ** 2 > 3 } 0 .. 99 ; 1 から 9 までのすべての double を含む配列:
私の@doubles = map { $_ * 2 } 1 .. 9 ; リオデジャネイロに拠点を置く顧客の名前の配列(ハッシュの配列から):
my @rjCustomers = map { $_ -> { state } eq "RJ" ? $_ -> { name } : ()} @customers ; 3 で割り切れる数値をフィルタリングする:
my @divisibleBy3 = grep { $_ % 3 == 0 } 0 .. 100 ; パワーシェル
$s = ( 0 .. 100 | ? { $_ * $_ -gt 3 } | % { 2 * $_ } )これは次の略記です:
$s = 0 .. 100 | where-object { $_ * $_ -gt 3 } | foreach -object { 2 * $_ }パイソン
Python では、有限リストのリスト内包表記を表現するために次の構文を使用します。
s : list [ int ] = [ 2 * x 、 xが 範囲内( 100 ) 、 x ** 2 > 3 の場合] ジェネレータ式は、入力に対して遅延評価を行う Python バージョン >= 2.4 で使用できます。また、連続する整数を返す count ジェネレータ関数などの「無限」の入力を反復処理するためにジェネレータと共に使用できます。
入力してitertoolsをインポートし、 Iteratorをインポートします。 s : イテレータ[ int ] = ( 2 * x 、 x 、itertools 内. count ( ) 、x ** 2 > 3 の場合) (ジェネレーター式をその後に使用すると、値の生成を停止するタイミングが決定されます)。
R
x <- 0 : 100 S <- 2 * x [ x ^ 2 > 3 ] ラケット
( for/list ([ x 100 ] #:when ( > ( * x x ) 3 )) ( * x 2 )) 複数のジェネレーターを使用した例:
( for*/list ([ x (範囲内1 21 )] [ y (範囲内1 21 )] [ z (範囲内1 21 )] #:when ( = ( + ( * x x ) ( * y y )) ( * z z ))) (リストx y z )) 楽
私の @s = ( $_ * 2 、 $_ ** 2 > 3の場合、 0 .. 99 ); スカラ
for 理解の使用:
val s = for ( x <- 0 to 100 ; if x * x > 3 )は2 * xを返します スキーム
リスト内包表記はSchemeではSRFI -42ライブラリの使用を通じてサポートされています。[3]
(リスト-ec ( : x 100 ) ( if ( > ( * x x ) 3 )) ( * x 2 )) 複数のジェネレータを使用したリストの理解の例:
(リスト-ec ( : x 1 21 ) ( : y x 21 ) ( : z y 21 ) ( if ( = ( + ( * x x ) ( * y y )) ( * z z ))) (リストx y z )) セトル
s := {2*x : x が {0..100} の範囲にある | x**2 > 3 };雑談
(( 1 ~: 100 )選択: [ : x | x の 2 乗 > 3 ])収集: [ : x | x * 2 ]ビジュアルプロローグ
S = [ 2 * X || X = list::getMember_nd ( L )、X * X > 3 ]
参考文献
- ^ Nim シュガーモジュール
- ^ OCaml 電池付属
- ^ Scheme SRFI 42: 積極的内包
外部リンク
- rosettacode.org におけるリスト内包表記の比較