タグ別アーカイブ: 配列

ruby

rubyでformを取得する【サンプル】

railsのようなフレームワークを使わずに、ruby単体でform(リクエスト)情報を取得する方法です。

現在のバージョン ruby 2.1 で動作確認を行っております。

rubyでformを取得する

cgiクラスを読込んで、cgi.newするだけで使えるので簡単です。
簡単ですが、少し気を付けたい点です。
・postもgetも、同じコードで取得できるので、意図しないgetに注意する。
・checkboxやname名が同じ要素等は、配列として渡されます。params(ハッシュに変換するメソッド)を使用してアクセスすると便利です。
・escapeHTMLメソッドで、エスケープする(XSS:クロスサイトスクリプティング対策)。

もちろん、実際に使用するときは、入力値のバリデーションも行いましょう。

require "cgi"
cgi = CGI.new

# リテラルの場合
# <input type="text" name="name" />
print cgi['name']

# 配列で渡される値の場合
# <input type="checkbox" name="checkbox" value="box1" />
# <input type="checkbox" name="checkbox" value="box2" />

# 個別にアクセス
print cgi.params['checkbox'][0]

# each でまとめてアクセス
objCgi.params['checkbox'].each do |i|
  print i,"<br>"
end

# エスケープ
print CGI.escapeHTML(cgi['name'])

rubyでformを取得するサンプル

railsのようなフレームワークを使わずに、ruby単体でリクエスト情報を取得するサンプルです。
rubyでformを取得する【サンプル】
#!/xxxx/lib/ruby の部分は環境に合わせて変更してください。

#!/xxxx/lib/ruby

require "cgi"
objCgi = CGI.new

# リクエストを、エスケープし, 文字列は文字列化, 数値は数値化
# objCgi : CGIインスタンス
# arrkeys : 配列のキー(チェックボックス等)
def requestParse(objCgi, *arrkeys)
  
  require "cgi"
  hashResult = Hash.new
  
  arrRequestKeys = objCgi.keys
  
  arrRequestKeys.each do |key|
    if (arrkeys.index(key) == nil) then
      temp = CGI.escapeHTML(objCgi[key].to_s.strip)
      if ( /^([0-9])+$/ =~ temp ) then
        temp = temp.to_i
      end
    else
      # 配列の時
      arrValue = objCgi.params[key]
      temp = Array.new
      arrValue.each do |value|
        val = CGI.escapeHTML(value.to_s.strip)
        if ( /^([0-9])+$/ =~ val ) then
          val = value.to_i
        end
        temp << val
      end
    end
      hashResult[key] = temp
  end
  
  return hashResult 
end

# リクエスト(post,get)と、配列のネームを渡します。
arrRequests = requestParse(objCgi, "checkbox", "checkbox2")

# チェックボックス判定
def checkflag(array, value)
  check = ""
  if (array.class == Array and array.index(value) != nil) then
      check = "checked"
  end
  return check;
end

print <<"HERE"
Content-Type: text/html

<!DOCTYPE html>
<html lang="ja" xml:lang="ja">
<head>
    <meta charset="UTF-8">
    <title>rubyでformを取得する【サンプル】</title>
</head>
<body>
<form action="#" method="post">
    <p>name : val1</p>
    <input type="text" name="val1" value="#{arrRequests['val1']}" />
    <p>name : val2</p>
    <input type="text" name="val2" value="#{arrRequests['val2']}" />
    <p>name : radio</p>
    <input type="radio" name="radio" value="radio1" #{ "checked" if arrRequests["radio"] == "radio1"} />radio
    <input type="radio" name="radio" value="radio2" #{ "checked" if arrRequests["radio"] == "radio2"} />radio2
    <input type="radio" name="radio" value="radio3" #{ "checked" if arrRequests["radio"] == "radio3"} />radio3<br />
    <br />
    <p>name : checkbox</p>
    <input type="checkbox" name="checkbox" value="momo" #{checkflag(arrRequests["checkbox"], 'momo')} />momo
    <input type="checkbox" name="checkbox" value="hana" #{checkflag(arrRequests["checkbox"], 'hana')} />hana
    <input type="checkbox" name="checkbox" value="kuri" #{checkflag(arrRequests["checkbox"], 'kuri')} />kuri
    <input type="checkbox" name="checkbox" value="2929" #{checkflag(arrRequests["checkbox"], 2929)} />2929<br />
    <br />
    <p>name : checkbox2</p>
    <input type="checkbox" name="checkbox2" value="1" #{checkflag(arrRequests["checkbox2"], 1)} />1
    <input type="checkbox" name="checkbox2" value="2" #{checkflag(arrRequests["checkbox2"], 2)} />2
    <input type="checkbox" name="checkbox2" value="3" #{checkflag(arrRequests["checkbox2"], 3)} />3
    <input type="checkbox" name="checkbox2" value="4" #{checkflag(arrRequests["checkbox2"], 4)} />4<br />
    <br />
    <p>name : textbox</p>
    <textarea name="textbox" rows="10" cols="50">#{arrRequests['textbox']}</textarea>
    <br />
    <input type="submit" name="submit" value="送信" />
</form>
HERE

print "</body></html>\n"

オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル

オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル

ruby

配列 メソッドについて

前回の続きです。前回配列の操作について記事にしましたが、ここでは配列クラスの標準メソッドで便利そうなのを抜粋します。
このページは随時追加更新していくと思います。

配列のメソッド(class Array)

Rubyのメソッドやメソッドの詳細を探すときは、リファレンスが一番です^^;
他にも、逆引きをまとめてくれている方のサイトなどとても助かります。ありがたく参考にしましょう。
メソッドは、当記事で一部を抜粋して紹介しております。

破壊的メソッド

メソッドの中には、レシーバ(元々のオブジェクト)自身の内容を変更してしまうものがあります。このようなメソッドをRubyでは『破壊的メソッド』と名付けられています。

下のsampleのように、「first」,「sort」メソッドはレシーバ(配列オブジェクト)自身には変化が無く、破壊的メソッドである「shift」,「sort!」実行後は、レシーバ自身に変更が反映されていることがわかります。

# 破壊しないメソッド
array = [5, 3, 8, 4]
p array.first => 5
p array => [5, 3, 8, 4]
p array.sort => [3, 4, 5, 8]
p array => [5, 3, 8, 4]

# 破壊的メソッド
array = [5, 3, 8, 4]
p array.shift => 5
p array => [3, 8, 4]
p array.sort! => [3, 4, 8]
p array => [3, 4, 8]

「sort」のように「!」が付いているものは確実に破壊的メソッドですが、「shift」のように見た目では分からないものもあります。(shiftの意味を考えれば破壊的メソッドです。)
メソッドが破壊的な振る舞いをするか曖昧な場合は、マニュアルやsampleなどで確認してから使用するようにしましょう。 特に配列は思っていた結果と違う場合などに、この辺を疑ってみると良いかもしれません。

メソッド(Class Array)

追加、削除など
.unshift # 先頭要素に追加
.shift # 先頭の要素を返し、レシーバの先頭要素を削除する
.push # 末尾に追加
.pop # 末尾の要素を返し、レシーバの末尾要素を削除する
.first # 最初の要素を返す
.last # 最後の要素を返す

.max # 要素の最大値を取得
.min # 要素の最小値を取得
length, size

配列の要素数を返す

array = [1, 2, 8, 4, 10]
p array.length # => 5
p array.size # => 5
array = [[1, 2], [8, 4, 10]]
p array.length # => 2
p array.size # => 2
# size, length はエイリアスの関係

知っとくと便利そうなメソッド

下記にサンプルを載せています。

.flatten # 多重配列を平坦化する。
.delete(x) # xの要素を全て取り除く
.reject # 条件に一致した場合、取り除く
.slice(x..y) # 指定した部分を取りだす
.uniq # 重複要素を削除する [1,1] => [1]
.sort # ソート
.reverse # 逆順にする
.join # 要素を任意の文字列で区切った文字列を取得
.split# 文字列を配列に変換
.select # 条件を満たす要素を抽出
.index # 要素を探すし、その位置を返す
.map # 各要素にブロックを実行し配列を返す
.choice # ランダムに取得する。
.max_by # 条件付きの最大値
.min_by # 条件付きの最小値
.transpose # 転置配列を返す
flatten

多重配列を平坦化する

array = [[1, 2], [8, 4, 10]]
p array.flatten # => [1, 2, 8, 4, 10]
p array # => [[1, 2], [8, 4, 10]]
p array.size # => 2
p array.flatten.size # => 5
delete

xの要素を全て取り除く

array = [ "momo", "banana", 100, 100, "momo" ]
p array.delete("momo") # => "momo"
p array # => ["banana", 100, 100]
reject

条件に一致した要素を取り除く(「reject!」)

array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
p array.reject { |val| val < 5 } # => [5, 6, 7, 8, 9]
p array # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
p array.reject! { |val| val < 5 } # => [5, 6, 7, 8, 9]
p array # => [5, 6, 7, 8, 9]
slice

指定した部分を取りだす(「slice!」取り除く)

array = [8, 3, 4, 6, 10, 2]
p array.slice(2,2) # => [4, 6]
p array.slice(2..4) # => [4, 6, 10]
p array.slice!(2,2) # => [4, 6]
p array # => [8, 3, 10, 2]
uniq

重複要素を削除する

array = [ "momo", "banana", 100, 100, "momo" ]
p array.uniq # => ["momo", "banana", 100]
p array # => ["momo", "banana", 100, 100, "momo"]
array.uniq! # => ["momo", "banana", 100]
p array # => ["momo", "banana", 100]
sort

ソート

array = [ 7, -2, 4, 10 ]
p array.sort # => [-2, 4, 7, 10]
p array # => [7, -2, 4, 10]
p array.sort! # => [-2, 4, 7, 10]
p array # => [-2, 4, 7, 10]
reverse

逆順にする

array = [ 7, -2, 4, 10 ]
p array.reverse # => [10, 4, -2, 7]
# 大きい順
p array.sort.reverse # => [10, 7, 4, -2]
p array # => [7, -2, 4, 10]
join

要素を任意の文字列で区切った文字列を取得

array = [ "momo", "banana", "mikan", "sumomo"]
p array.join("+") # => "momo+banana+mikan+sumomo"
p array.join(",") # => "momo,banana,mikan,sumomo"
p array.join() # => "momobananamikansumomo"
split

文字列を任意の文字列で区切り配列に変換

text = "hoge\nmoge\ntoge\n"
p array = text.split("\n") # => ["hoge", "moge", "toge"]
text = "123,456,789"
p array = text.split(",") # => ["123", "456", "789"]
text = "123,456,789"
p array = text.split(",").map(&:to_i) # => [123, 456, 789]
index

要素を探すし、その位置を返す。

array = [ "banana", 100, 352.6, 9, 100 ]
p array.index("banana") # => 0
p array.index(352.6) # => 2
p array.index(300) # => nil
# 文字列時
string = "cototoco.jp"
p string.index(".") # => 8
sample(x)

x個の要素をランダムに取得する

array = [ "momo", "banana", "mikan", "sumomo"]
p array.sample # => "banana"
p array.sample(2) => ["sumomo", "mikan"]
p array = [ "momo", "banana", "mikan", "sumomo"]
max_by,min_by

条件付きの最大値,条件付きの最小値

array = [ "momo", "banana", "mikan", "sumomo"]
p array.max_by {|val| val.length } # => "banana"
array = [ 2, -6, 5, 8 ]
p array.min_by {|val| val * val } # => 2
transpose

転置配列を返す

array = [[1,2,3],[4,5,6],[7,8,9]]
p array.transpose # => [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
p *ary.transpose
# => [1, 4, 7]
# => [2, 5, 8]
# => [3, 6, 9]
p array # => [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

配列からハッシュを作る(おまけ)

array = ["apple", 50, "banana", 100, "orange", 150]
hash = Hash[*array]
p hash # => {"apple"=>50, "banana"=>100, "orange"=>150}

オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル

逆引きRuby – 逆引きRuby

配列 – 逆引きRuby

ruby

Ruby 配列の操作

配列の操作

ドットインストールのRuby入門をみて、
Rubyの配列操作が新鮮だったので、覚える自信がないのでメモ

配列

array = [3, 4, 7]
p array[1] # => 4
array[1] = 10
p array # => [3, 10, 7]
p array[0..2] # => [3, 10, 7] 0 ~ 2 まで (*1
p array[0...2] # => [3, 10] 0 ~ 2 未満 (*1
p array[-1] # => 7 最後の要素
p array[1, 2] # => [10, 7] 1番目の要素から、2個分とってくる

配列操作

array2 = [6, 3, 8, 10]
array2[0...2] = [7, 1] # 0~2未満を書き換える
p array2 # => [7, 1, 8, 10]
array2[1, 0] = [14, 26, 22] # 一番目の要素から、0番目の要素に、追加する
p array2 # => [7, 14, 26, 22, 1, 8, 10]
array2[0, 2] = [] # 0~2個までを空にする
p array2 # => [26, 22, 1, 8, 10]

配列メソッド

p array2.size # => 5 サイズ
p array2.sort # => [1, 8, 10, 22, 26] 小さい順に出力
p array2.sort.reverse # => [26, 22, 10, 8, 1] 小さい順を逆順に出力
p array2 # => [26, 22, 1, 8, 10] 元の配列は変わっていない
p array2.push(100) # => [26, 22, 1, 8, 10, 100] 末尾に追加
array2 << 101 << 201 # 末尾に追加のショートカット
p array2 # => [26, 22, 1, 8, 10, 100, 101, 201]

配列メソッドについては、もう少し詳しく次回まとめます

配列の演算

Rubyは配列どうしの演算(演算というより集合)ができます。

arr1 = [1, 2, 4]
arr2 = [2, 4, 6]

# 共通部分(and演算)
p arr1 & arr2 # => [2, 4]
# 和集合(or演算)
p arr1 | arr2 # => [1, 2, 4, 6]
# 差
p arr1 - arr2 # => [1]
# 和
p arr1 + arr2 # => [1, 2, 4, 2, 4, 6]

配列を変数に分割

関数の戻り値で配列を返す時などに便利です。phpでのlist関数みたいな感じです。

def data_back
    return data = [ "apple", 100 ]
end
name, price = data_back
p name # => "apple"
p price # => 100

*1)『..』と『…』は『範囲オブジェクト』というオブジェクトを作る記号です
こんな使い方もできます。日本語はヤバイです。

# to_a : 配列に変換する
arrTemp = (1..10).to_a
p arrTemp # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arrTemp = ("a".."g").to_a
p arrTemp # => ["a", "b", "c", "d", "e", "f", "g"]
arrTemp = ("え".."く").to_a
p arrTemp # => ["え", "ぉ", "お", "か", "が", "き", "ぎ", "く"]

Rubyで二Ruby入門 (全23回) – プログラミングならドットインストール

ruby

Ruby 配列の初期化と多重配列

環境もそろってきたので、記述のメモなど残していきます。

配列に関すること

宣言

arr = Array.new()
arr = Array.new # 等価
arr = [] # 等価
p arr # []

初期化

hoge_0 = [1,2,3]
p hoge_0 # => [1, 2, 3]
hoge_1 = [[1,2,3],[4,5,6]]
p hoge_1 # => [[1, 2, 3], [4, 5, 6]]

rubyなら出来そうで出来ない初期化、以前のversionではOK?

hoge_2[] = "hoge" # => エラー
hoge_3[0] = "hoge" # => エラー

new での初期化

arr = Array.new()
p arr # => []

arr = Array.new(3)
p arr # => [nil,nil,nil]

arr = Array.new(3, 1)
p arr # => [1,1,1]
arr[1] = 2
p arr # => [1, 2, 1]

ランダム値の初期化を考える

arr = Array.new(3, rand(1..9))
p arr # => [x,x,x] 要素が同じ値に(上記l.8参照)なってしまうので、ブロックを用いる

arr = Array.new(3){ rand(1..9) }
p arr # => [x,y,z] 要素3こが1~9のランダムな値

多次元配列の宣言の前に注意点!
このように書いてしまうとおかしなことになる

arr = Array.new(3,Array.new(3))
arr[1][1] = 2
p arr # => [[nil, 2, nil], [nil, 2, nil], [nil, 2, nil]]

上は、a[1][1]の要素を変更したのに、その他の配列(object)も変更されています。
参考 Rubyで二次元配列の初期化 – simanmanのブログ

オブジェクトのIDを確認すると、同じ値となっています。

p arr.map(&:object_id) # => [17525590, 17525590, 17525590]

多次元配列はブロックを使用して宣言する。
ランダム値の初期化の時と同様に、ここでもブロックを使います。

arr = Array.new(3){ Array.new(3) }
arr = Array.new(3).map{ Array.new(3) } # 同意 mapメソッドは、要素の数だけ繰り返しブロックを実行
p arr # => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
arr[1][1] = 2
p arr # => [[nil, nil, nil], [nil, 2, nil], [nil, nil, nil]]

上のように宣言することで、arr[1][1]の値のみ変更されます。
また、オブジェクトIDを確認すると、それぞれのオブジェクトとなっています。

p arr.map(&:object_id) # => [17918240, 17918230, 17918220]

多次元配列を初期化する
ランダム値の初期化の時と同様に、ここでもブロックを使います。

arr = Array.new(3){ Array.new(3, 1) }
p arr # => [[1, 1, 1], [1, 1, 1], [1, 1, 1]]

arr = Array.new(3){ |i| Array.new(3){ |j| i+j } }
p arr # => [[0, 1, 2], [1, 2, 3], [2, 3, 4]]

Rubyで二次元配列の初期化 – simanmanのブログ