どぼじょのIT学習ブログ

高専卒土木女子がIT業界を目指してお勉強。

Ruby入門 part11

Ruby入門、標準ライブラリについての続きです🎈
これでRuby入門は最後になります!長かった〜!
この記事もそれなりに長いです😂笑

目次

1.配列(Array)クラス

1-1. 要素の置き換え、追加

配列オブジェクトについてはこちらの記事で学習したとおりですが、インデックスという数値を使って他のオブジェクトを管理できるものでした💡
インデックスは先頭の要素を 0 として、1, 2, 3, ... と増えていくものでした。
そして、配列に含まれる要素を取得するには次のように行います。
1つの要素を取得する方法と、複数の要素を配列として取得する方法を続けて記載いたします。

変数名 = 配列オブジェクト名[インデックス]
新しい配列オブジェクト名 = 配列オブジェクト名[開始位置..終了位置]

また、配列に含まれる要素を別の要素に置き換えることもできます。

配列オブジェクト名[インデックス] = 新しい要素
配列オブジェクト名[開始位置..終了位置] = 新しい要素
配列オブジェクト名[開始位置, 要素の数] = 新しい要素

要素を追加するには、上記の3つめの方法を応用して、引数の「要素の数」を0にすることで、開始位置に新しい要素を追加できます✨

これまでの解説をまとめて実際にやってみました!

gist.github.com
結果は以下のとおりです。
f:id:mistyrinth:20181129180354p:plain

1-2. 配列の平滑化

配列オブジェクトの中の要素に他の配列があるとき、中の配列を展開して平滑化することができます。 Arrayクラスで用意されているflattenメソッドを使います。

配列オブジェクト名.flatten

具体的には以下のようになります。
ここでは、配列の中のひとつの要素に["塩", "胡椒"]という配列が入っていますが、これを展開して平滑化しています🌝

gist.github.com
結果は以下のようになります。
f:id:mistyrinth:20181129183136p:plain

1-3. 要素を取り除くメソッド

ここからは要素を取り除くメソッドをいくつか紹介します。

メソッド 動作 備考
uniq 重複要素を取り除いて配列を作成
uniq! 重複要素を取り除いて配列を上書き
compact nilの要素を取り除いて配列を作成
compact! nilの要素を取り除いて配列を上書き
delete 指定した値と等しい要素を取り除いて上書き 引数あり
delete_at 指定したインデックスの要素を取り除いて上書き 引数あり
delete_if ブロック内の処理結果がtrueの要素を取り除いて上書き 解説後述

沢山ありますね!!
delete_ifは、以下のように書くことができます。rejectも同様です😊

配列オブジェクト名.delete_if {|x|
    実行する処理
}

uniqのように新しく配列を作成するメソッドに対して、deleteのように自身を上書きするメソッドを破壊的メソッドといいます。
新しく作成するメソッドなのか、上書きするメソッドなのかを把握しながら実行しないと、予期せぬ戻り値になります笑
ちなみにわたしはdeleteが新規作成メソッドだと思いこんでいたら、取り除きたい値だけが戻り値になって返ってきてしまい、苦戦しました😂

ひとつひとつ試していきます!

gist.github.com

結果は以下のとおりです。
f:id:mistyrinth:20181129212617p:plain

1-4. 並び替えメソッド

削除の次は、要素を並び替えるために使えるメソッドを紹介します😋

メソッド 動作 備考
reverse 要素を逆順に並び替えて配列を作成
reverse! 要素を逆順に並び替えて配列を上書き
sort 要素を一定の規則でソートして配列を作成 解説後述
sort! 要素を一定の規則でソートして配列を上書き
transpose 配列を行列とみなす(行と列を入れ替える) 解説後述

sortメソッドは、以下のようにブロックを使ってソートする方法を指定することができます。

Arrayオブジェクト.sort {|a, b|
    aとbを使った比較の方法
}

なお、比較方式を指定しない場合には各要素を<=>メソッドが使われます。この場合、要素は小さい順に並べ替えられます。

transposeメソッドは、配列(左から右へ)を行列(上から下へ)として入れ替えるメソッドです。
行と列が入れ替わるというイメージですね😶

これらを実際に試してみます!

gist.github.com

結果は以下のとおりです。
f:id:mistyrinth:20181129215028p:plain

2.ハッシュ(Hash)クラス

ハッシュについてはこちらの記事で学習しましたが、他にもHashクラスで使えるメソッドがあるので紹介します💡

メソッド 動作 備考
delete 指定したキーに対応する値を取り除いて上書き 解説後述
delete_if ブロック内の処理結果がtrueのキーと対応する値を取り除いて上書き 解説後述
reject! 同上
relect ブロック内の処理結果がtrueのキーと対応する値を取り除いたハッシュを作成
clear ハッシュを空の状態にする

先程も出てきたdelete系のメソッドがHashクラスにも用意されていますね〜😐
指定したキーに対応する値を、ハッシュ自身から取り除きます。破壊的メソッドですね🔥
戻り値は削除された値になります。

deleteメソッドでは、指定したキーが存在しない場合の処理をブロックに指定することもできます!

ハッシュオブジェクト名.delete(キー) {|key|
    ...
}

delete_ifメソッドは次のように書くことができます。
同じ動作をするreject!メソッドも同様です👌

ハッシュオブジェクト名.delete_if {|key, value|
    ...
}

実際にやってみます!

gist.github.com
結果は以下のとおりです。
f:id:mistyrinth:20181201130625p:plain

3.時刻(Time)クラス

3-1. Timeオブジェクトの作成

今度は初登場のTimeクラスです。時刻を扱うクラスですね🕑

Timeクラスから作成できるTimeオブジェクトには、起算時と呼ばれる時刻から現在までの経過秒数を持っています。
起算時は、一般的には1970年1月1日午前0時です。
なぜかというのはちょっと調べてみただけではよく分かりませんでしたが、世界的な基準やらUNIXのシステムやらがそうなっているらしいです😶

Timeオブジェクトを作成するには、おなじみnewメソッドを使います。

Timeオブジェクトを格納する変数 = Time.new

newメソッドの他にnowメソッドを使うこともできます。

Timeクラスには、オブジェクトの経過秒数から時刻を構成する要素を取り出すメソッドがいくつか用意されています。

メソッド 動作
sec 秒を整数で取得
min 分を整数で取得
hour 時を整数で取得
day 日を整数で取得
mday 同上
month 月を整数で取得
mon 同上
year 年を整数で取得
wday 曜日を0(日)から6(土)の整数で取得
yday 1月1日からの通算日を整数で取得
isdst 夏時間があるなら true
dst? 同上
zone タイムゾーンを表す文字列を取得

沢山ありますね😳
これらを組み合わせてプログラムを書いてみました!

gist.github.com

結果は以下のとおりです。
f:id:mistyrinth:20181201135604p:plain
実行した時の時刻が表示されました!🎉

現在時刻ではなく、指定した日時を表すTimeオブジェクトを作成するには、Timeクラスで用意されているlocalメソッドを使います。また、mktimeメソッドを使っても同じです。
localメソッド(またはmktimeメソッド)の引数には以下の2種類があります。

Time.local(year, month, day, hour, min, sec, usec)
Time.local(sec, min, hour, day, month, year, wday, yday, isdst, zone)

ひとつめの引数は、年、月、日、時間、…という順で作っていきます。usecはマイクロ秒のことです😊
途中から省略することもでき、その場合は省略された引数には取り得る最小値が代入されます。
ふたつめの引数は、秒、分、時間、…という順です。
こちらは引数を省略できず全て指定するのですが、wday, yday, zoneは設定しても無視されるようです笑
isdstサマータイムの有無を指し、値はtrueまたはfalseです。

3-2. Timeオブジェクトを文字列として取得

Timeオブジェクトを指定したフォーマットで文字列として取得するには、Timeクラスで用意されているstrftimeメソッドを使います。

変数 = Timeオブジェクト名.strftime(フォーマット文字列)

引数のフォーマット文字列とは、出力したい形式を表す文字列です。以下のような特別な文字列を使って指定することができます。

フォーマット文字列 出力形式 出力例
%A 曜日 Sunday, Monday, ...
%a 曜日の省略形 Sun, Mon, ...
%B 月(文字) January, February, ...
%b 月(文字)の省略形 Jan, Feb, ...
%c 日付と時刻
%d 01 〜 31
%H 24時間制の時 00 〜 23
%I 12時間制の時 01 〜 12
%j 年中の通算日 001 〜 366
%M 00 〜 59
%m 月(数字) 01 〜 12
%p 午前または午後 AM,PM
%S 00 〜 60 (60はうるう秒)
%U 週番号(最初の日曜日が第1週) 00 〜 53
%W 週番号(最初の月曜日が第1週) 00 〜 53
%w 曜日を表す数(日曜日が0) 0 〜 6
%X 時刻
%x 日付
%Y 西暦
%y 西暦の下2桁 00 〜 99
%Z タイムゾーン
%% %自身

沢山あって、覚えるのは難しそうですね💦
実際にやってみると、次のようになります。

gist.github.com
結果は以下のとおりです。
f:id:mistyrinth:20181201192528p:plain

3-3. 時刻の取得

Timeクラスには、時刻を取得するためのメソッドがいくつかあります。

メソッド 動作 備考
to_a Timeオブジェクトの各要素を配列として取得 解説後述
to_f 起算時からの経過秒数を浮動小数点数で取得
to_i 起算時からの経過秒数を整数で取得
tv_sec 同上
utc_offset 現在のタイムゾーン協定世界時との時差を取得
gmt_offset 同上
gmtoff 同上

to_aメソッドで取得できる時刻の要素は、次の順番で配列に格納されます。
[sec, min, hour, mday, month, year, wday, yday, isdst, zone]

これらを実際に試してみました!
gist.github.com

結果は以下のとおりです。
f:id:mistyrinth:20181201210445p:plain

4.日付(Date、DateTime)クラス

4-1. Dateクラス

Dateクラスは日付を扱うクラスですが、Ruby公式では推奨されていないらしいです。将来的になくなるとか🧐
Dateクラスは組み込みクラスではないため、Dateクラスを使うにはまずプログラムファイルの中で次の一文を記述する必要があります。

require "date"

Dateクラスのオブジェクトを作成するには、newメソッドを使って年月日を指定するか、todayメソッドを使って本日の日付を取得する方法があります。

Date.new(year, month, day)
Data.today

DataクラスのオブジェクトはTimeオブジェクトと同様に、dayメソッドなどを使って時刻を取得したり、フォーマット文字列を使って文字列を取得することができます。

4-2. DateTimeクラス

DateTimeクラスはDateクラスのサブクラスで、Dateクラスの年月日に加え、時分秒を扱うことができます💡
DateTimeクラスも当然組み込みクラスではないため、始めにプログラムファイルの中でrequire "date"を記述する必要があります。

DateTimeクラスのオブジェクトを作成するには、newメソッドで任意の時間を指定するか、nowメソッドで現在の時刻を取得します。

Date.new(year, month, day, hour, min, sec, offset)
DateTime.now([start])

offsetは、協定世界時との時差を指定します。単位はです🌞
例えば、日本の時差(9時間)を表すには9[時間] / 24[時間]日の0.375日となります。

Ruby入門、以上です!長々ありがとうございました😆