Module: QueryStream::Singularize

Defined in:
lib/query_stream/singularize.rb

Overview

英単語の複数形→単数形変換モジュール

Class Method Summary collapse

Class Method Details

.call(word) ⇒ String

複数形の英単語を単数形に変換する

Parameters:

  • word (String)

    変換対象の単語

Returns:

  • (String)

    単数形の単語



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/query_stream/singularize.rb', line 27

def call(word)
  str = word.to_s

  # アンダースコア付きの複合名は、末尾の s で終わるセグメントを単数化する
  # physics_books → physics_book, books_nested → book_nested, books2 → book2
  if str.include?('_')
    segments = str.split('_')
    # people は不規則変化なので優先的に単数化
    people_idx = segments.index { it.match?(/\Apeople\z/i) }
    if people_idx
      segments[people_idx] = singularize_simple(segments[people_idx])
      return segments.join('_')
    end
    # 末尾から探して最初に見つかった複数形セグメントを単数化
    idx = segments.rindex { singularize_simple(it) != it }
    if idx
      segments[idx] = singularize_simple(segments[idx])
      return segments.join('_')
    end
  end

  singularize_simple(str)
end

.singularize_simple(word) ⇒ Object

単一単語の単数化



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/query_stream/singularize.rb', line 52

def singularize_simple(word)
  case word.to_s
  in /\Apeople(.*)\z/i             then "person#{$1}"
  in /\A(.+)ies\z/                 then "#{$1}y"
  in /\A(.+)([sxz]|ch|sh)es\z/    then "#{$1}#{$2}"
  in /\A(.+)ves\z/                 then "#{$1}f"
  in /\A(.+?)s([0-9].*)\z/         then "#{$1}#{$2}"
  in /\A(.+)s\z/                   then $1
  else word
  end
end