プロが教える店舗&オフィスのセキュリティ対策術

rubyとscalaを書き始めた初心者です。

以下のような型の変換のプログラムを作成しようと考えていたのですが、
エラーが出てしまったので、ご教示頂きたいです。

■変換前
Map("age"->"3", "reason"->"sounds good", "check"->Array("1", "2"), "check_pre"->"1,2")

■変換後
Map("age"->3, "reason"->"sounds good", check"->Array(1,2), "check_pre"->Array(1,2))

■変換の条件
・Mapのvalueは変換なし。
・Mapのvalueは全てString型
・valueが数値のものはInt型に変換。
・valueが配列のものはInt型の配列に変換。
・valueがカンマ区切りの文字列は、Int型の配列に変換。

途中まで作成したのですが、エラーが出てしまいました。
================================
■プログラム
val params = Map("age"->"3", "reason"->"sounds good", "check"->Array("1", "2"), "check_pre"->"1,2")

val new_params = params.mapValues{
case str if str.isInstanceOf[Array[String]] => str.map(_.toInt)
case str if str.matches("""^\d+$""") => str.toInt
case str if str.matches("""^(\d,)+\d$""") => str.split(",").map(_.toInt)
}

new_params.foreach(print)

■エラー内容
error: value matches is not a member of java.io.Serializable
================================


また、少々余談なのですが、
rubyだと、このようなパターンマッチは扱えないという認識で宜しいでしょうか。
(その場合は、filterやmergeを繰り返せばできると考えておりますが、
 あまりスマートではないですかね……。)
rubyの場合の実装の指針等もございましたら、合わせてご教示頂きたいです。


宜しくお願いします。

A 回答 (1件)

Rubyですが、



params = {"age"=>"3", "reason"=>"sounds good","check"=>["1","2"],"check_pre"=>"1,2"}

result = params.each_with_object({}) do |(k,v),x|
v = case v
when /\A\d+\z/
v.to_i
when /\A\d+(,\d+)\z/
v.split(/,/).map(&:to_i)
when String
v
when Array
v.map{|w| /\A\d+\z/=~w ? w.to_i : w }
else
raise "ERROR value=#{v.inspect}"
end
x[k]=v
end

p result
    • good
    • 0
この回答へのお礼

HAPPY

素早い回答ありがとうございます!
rubyでもcase文で書けたのですね……。
each_with_objectも知らなかったです。
プログラム例も記載していただき、誠にありがとうございます!
とても、勉強になりました!

引き続き、scalaについても回答募集しております。

お礼日時:2015/06/06 17:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!