LoginSignup
2
0

More than 3 years have passed since last update.

CodeWarでの勉強(ruby)③ squeeze, gsub

Posted at

この記事について

最近始めたCodewarを通じて学べたことを少しずつアウトプット

問題

Implement the function unique_in_order which takes as argument a sequence and returns a list of items without any elements with the same value next to each other and preserving the original order of elements.

関数unique_in_orderを使って引数としてシーケンス?を受け取り、同じ値が隣接してなくて、要素の順番にしてリストを返すようにさせる。

unique_in_order('AAAABBBCCDAABBB') == ['A', 'B', 'C', 'D', 'A', 'B']
unique_in_order('ABBCcAD')         == ['A', 'B', 'C', 'c', 'A', 'D']
unique_in_order([1,2,2,3,3])       == [1,2,3]

僕が考えた方法

①繰り返して使われている値を消そうと思って、受け取った引数を配列に直してからuniqにしようと思ったけど、以下のようになるから失敗。


def unique_in_order(iterable)
  iterable.chars.uniq
end

unique_in_order('AAAABBBCCDAABBB')
=>["A", "B", "C", "D"]

②連続した値を一纏めにできないかと思って検索すると、squeezeメソッドを知った。
https://docs.ruby-lang.org/ja/latest/method/String/i/squeeze.html

squeeze(*chars) -> String[permalink][rdoc][edit]
chars に含まれる文字が複数並んでいたら 1 文字にまとめます。

def unique_in_order(iterable)
  iterable.squeeze.chars
end

unique_in_order('AAAABBBCCDAABBB')
=>["A", "B", "C", "D", "A", "B"]

できたぜ!!!!

しかしまだ終わらない

提出すると以下のように3つのことで怒られた❤️

 <NoMethodError: undefined method `squeeze' for []:Array>
② <NoMethodError: undefined method `squeeze' for [1, 2, 3, 3]:Array>
③ <NoMethodError: undefined method `squeeze' for ["a", "b", "b"]:Array>

全てに共通しているのは配列に対してsuqueezeは使えないということだ。

つまり

引数が文字列の場合にiterable.squeeze.charsを実行して、配列の場合はiterable.uniqをやってやったらいいんじゃないのか?

成功したぜ!!!

def unique_in_order(iterable)
  if iterable.class == String
    iterable.squeeze.chars
  else
    iterable.uniq
  end
end

理想の回答

def unique_in_order(iterable)
  case iterable
    when String
      iterable.gsub(/(.)\1*/, '\1').split('')
    when Array
      iterable.uniq
  end
end

あ、ちょ待って。分からへん(笑)

gsubメソッド

gsub(pattern, replace) -> String
文字列中で pattern にマッチする部分全てを文字列 replace で置き換えた文字列を生成して返します。

#正規表現を使わない場合
#文字列.gsub(置換したい文字列, 置換後の文字列)

#正規表現を使う場合
#文字列.gsub(/正規表現/, 正規表現に該当した箇所を置換した後の文字列)

p 'abcdefg'.gsub(/def/, '!!')          # => "abc!!g"
p 'abcabc'.gsub(/b/, '<<\&>>')         # => "a<<b>>ca<<b>>c"
p 'xxbbxbb'.gsub(/x+(b+)/, 'X<<\1>>')  # => "X<<bb>>X<<bb>>"
p '2.5'.gsub('.', ',') # => "2,5"

正規表現を使ってやっているのか〜。
ここに関してはもうちょっと調べてから更新するようにします!

2
0
3

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
2
0