Julia の内包表記いろいろ

# 内包表記
ChatGPT
>内包表記（ないほうひょうき）は、プログラミング言語において、リストや配列などのデータ構造を生成するための構文の一つです。一般的に、リスト内包表記や集合内包表記として知られており、簡潔な記述で要素を生成することができます。Pythonなどの言語でよく使われます。


## 内包表記要素に対する変換式

### 基本
```julia
a = [10^i for i in 1:5]
@show a
```
```julia:結果
a = [10, 100, 1000, 10000, 100000]
5-element Vector{Int64}:
     10
    100
   1000
  10000
 100000
 ```

### タプルを返す
```julia
a = [(i,10^i) for i in 1:5]
@show a
```
```julia:結果
a = [(1, 10), (2, 100), (3, 1000), (4, 10000), (5, 100000)]
5-element Vector{Tuple{Int64, Int64}}:
 (1, 10)
 (2, 100)
 (3, 1000)
 (4, 10000)
 (5, 100000)
 ```

### 条件をつける
```julia
a = [(if i<3 10^i else 2^i end) for i in 1:5]
#または a = [ifelse(i<3, 10^i, 2^i) for i in 1:5]
@show a
```
```julia:結果
a = [10, 100, 8, 16, 32]
5-element Vector{Int64}:
  10
 100
   8
  16
  32
```

### 即時関数を実行させる
```julia
a = [(x -> if x<3 10^x else 2^x end)(i) for i in 1:5]
    #(i -> if i<3 10^i else 2^i end)(i) でも構わないが、意図を強調するためxを使用
@show a
```
```julia:結果
a = [10, 100, 8, 16, 32]
5-element Vector{Int64}:
  10
 100
   8
  16
  32
```

## フィルタ条件
### 例：偶数のみ
```julia
a = [i for i in 1:10 if i%2==0]
@show a
```
```julia:結果
a = [2, 4, 6, 8, 10]
5-element Vector{Int64}:
  2
  4
  6
  8
 10
```

### bool型を返す即時関数を実行させる
```julia
a = [i for i in 1:10 if(x -> if x%2==0 true else false end)(i)]
                      #(i -> if i%2==0 true else false end)(i) でも構わないが、意図を強調するためxを使用
@show a
```
```julia:結果
a = [2, 4, 6, 8, 10]
5-element Vector{Int64}:
  2
  4
  6
  8
 10
```
## 行列2次元配列
```julia
a = [i+10j+1 for i=0:9, j=0:2]
@show a
```
```julia:結果
a = [1 11 21; 2 12 22; 3 13 23; 4 14 24; 5 15 25; 6 16 26; 7 17 27; 8 18 28; 9 19 29; 10 20 30]
10×3 Matrix{Int64}:
  1  11  21
  2  12  22
  3  13  23
  4  14  24
  5  15  25
  6  16  26
  7  17  27
  8  18  28
  9  19  29
 10  20  30
```


## 二重ループ
```julia
@enum Suit ♠ ♣ ♦ ♥
struct Card
  suit::Suit
  rank::Int
end
deck = [Card(suit, rank) for suit in instances(Suit) for rank in 1:13]
```
```julia:結果
52-element Vector{Card}:
 Card(♠, 1)
 Card(♠, 2)
 Card(♠, 3)
 Card(♠, 4)
 Card(♠, 5)
 Card(♠, 6)
 Card(♠, 7)
 ⋮
 Card(♥, 8)
 Card(♥, 9)
 Card(♥, 10)
 Card(♥, 11)
 Card(♥, 12)
 Card(♥, 13)
```

## 配列の拡張(n倍に拡張)
```julia
#上記のコードの続き
#配列を3倍にする
n=3
decks = [deck for _ in 1:n] |> (x -> vcat(x...))
#decks = repeat(deck,n) #でも同じでした
```
```julia:結果
156-element Vector{Card}:
 Card(♠, 1)
 Card(♠, 2)
 Card(♠, 3)
 ⋮
 Card(♥, 12)
 Card(♥, 13)
```

## 入れ子にすれば~~2次元配列~~ジャグ配列も作れる
@antimon2 さんのコメント受けて修正しました
```julia
a = [[i+10j+1 for j in 0:2] for i in 0:9]
@show a
@show typeof(a)
for x in a
  @show x
end
```
```julia:結果
a = [[1, 11, 21], [2, 12, 22], [3, 13, 23], [4, 14, 24], [5, 15, 25], [6, 16, 26], [7, 17, 27], [8, 18, 28], [9, 19, 29], [10, 20, 30]]
typeof(a) = Vector{Vector{Int64}}
x = [1, 11, 21]
x = [2, 12, 22]
x = [3, 13, 23]
x = [4, 14, 24]
x = [5, 15, 25]
x = [6, 16, 26]
x = [7, 17, 27]
x = [8, 18, 28]
x = [9, 19, 29]
x = [10, 20, 30]
```


# ジェネレータ

ChatGPT
>ジェネレータ（Generator）は、プログラム内で反復処理を行う際に次々に値を生成する関数や機構のことです。ジェネレータは、メモリ効率やパフォーマンスの観点から非常に有用であり、反復可能なシーケンスを生成するために頻繁に使用されます。
ジェネレータは通常、反復処理中に値を保持せず、必要な値を必要に応じて動的に生成します。これにより、大規模なデータセットや無限のシーケンスを効率的に処理できます。
PythonやJuliaなどの多くのプログラミング言語では、ジェネレータを作成するための特別な構文や機能が提供されています。これにより、ジェネレータを容易に作成し、利用することができます。

### 基本
```julia
a = (10^i for i in 1:5)
@show a
for x in a
  @show x
end
```
```julia:結果
a = Base.Generator{UnitRange{Int64}, var"#83#84"}(var"#83#84"(), 1:5)
x = 10
x = 100
x = 1000
x = 10000
x = 100000
```

[]を()に変えると、内包表記と同様の構文が使える


# 参考記事
https://qiita.com/keta-sts136/items/c079aab0b4edf29c0472