0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Redのエモい関数たち

Last updated at Posted at 2018-06-30

Redのおもしろい関数を紹介

Red言語には他の言語にはないユニークな関数に遭遇します。独特の挙動をするので、使いこなすと他の言語ではできない書き方ができて、おもしろいです。
ここでは私が気に入っているエモい関数たちを紹介します。

collect

collect関数は、引数のブロックの中でkeepキーワードの直後に現れた要素だけ返します。以下は最もシンプルな例です。

collect [1 keep 2 3 4 keep 5]
; == [2 5]

この例だとなにがうれしいねん、これという感じですが、ブロック内で自由にコードが書けるので、非常に柔軟です。たとえば、以下のような感じです。

; ブロックから奇数だけ取得
numbers: [1 4 9 7 2]
collect [foreach n numbers [if odd? n [keep n]]]
; == [1 9 7]
; 関数型のmap関数のような使い方
; 各文字列の長さを取得
animals: ["dog" "cat" "bird" "elephant"]
collect [foreach animal animals [keep length? animal]]
; == [3 3 4 8]
; 辞書データを作る
animals: ["dog" "cat" "bird" "elephant"]
make map! collect [foreach animal animals [keep animal keep length? animal]]
; == #(
;     "dog" 3
;     "cat" 3
;     "bird" 4
;     "elephant" 8
; )

私は普段、C#を使っている時はなんでもLINQで書きたい病ですが、Redではなんでもcollectしたい病です

compose

composeは渡されたブロックの中で( )が付いている箇所だけ評価します。

a: 1 b: 2 c: 3
compose [a (b) c]
; == [a 2 c]

動的にコードを組みたい時などに重宝します。

; ここは日本か?
in-japan?: true

; 日本だったら日本語の「あいさつ.txt」からあいさつメッセージを読み込む
; 日本でなければ英語の「greeting.txt」からあいさつメッセージを読み込む
; なお、「%」で始まるのはfile!型のリテラルです。
message: read either in-japan? [%あいさつ.txt][%greeting.txt]

; あいさつメッセージを出力する関数を作る
say-hello: function [] compose [print (message)]
; == func [][print "こんにちは"]

any

anyはブロックの中の最初のtrueだったものを返します。
どちらかと言うとtruthy1だったもの、という方がいいかもしれません。
Redでは**falseとnoneだけがfalsy(偽)になり、それ以外はすべてtruthy(真)**です。単純な例としては、以下のようにif文で短絡評価のために使います。

if any [
    2 < 1
    2 < 3
    4 < 3
][
    print "どれかがtrueです"
]
; どれかがtrueです。

なお、他の言語だとanyという文言の関数は戻り値がtrue/falseなことが多いですが、Redでは値そのものが返ります。

any [false 7]
; == 7

このことと、noneはfalsyであるということを利用して、以下のようにnull合体演算子っぽい使い方が可能です。

a: none
b: any [a "noneの場合の値"]
print b
; noneの場合の値
; 以下はRedの辞書リテラル
; 犬は1匹、猫は2匹いる
animal-count: #(
    dog 1
    cat 2
)

print ["猫は" any [animal-count/cat 0] "匹です"]
; 猫は 2 匹です

foreach

foreachは基本的には他の言語と同じ役割で、ブロックの要素を1つずつ列挙して処理します。
列挙用のwordは任意の名称を使えます。

animals: ["dog" "cat" "bird" "elephant"]

; ここではanimalが列挙用のword
foreach animal animals [print animal]
; dog
; cat
; bird
; elephant

しかし、Redではブロックを使うことで列挙用のwordを複数指定でき、1ループでいくつ取り出すかを調整できます。

animals: ["dog" "cat" "bird" "elephant"]

; ここではx,yが列挙用のword
; wordの数が2個だと、2個ずつ取り出してくれる。
foreach [x y] animals [print [x "and" y]]
; dog and cat
; bird and elephant

まとめ

Redのユニークな関数や、ちょっとめずらしい関数の使い方をご紹介しました。
Redを触られる際はぜひ使ってみてください。

  1. 日本語訳が難しいですが、Mozillaでは「trueとみなされるもの」と訳されていますね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?