Чистый рубиновый код для разделения строки с определенными правилами - PullRequest
1 голос
/ 21 января 2011

представьте массив, подобный этому

[
"A definition 1: this is the definition text",
"A definition 2: this is some other definition text",
"B definition 3: this could be: the definition text"
]

Я хочу получить следующий хеш

hash = {
:A => ["A definition 1", "this is the definition text", "A definition 2", "this is some other definition text"], 
:B => ["B definition 3", "this could be: the definition text"]
}

Я создаю глоссарий с хэшем каждой буквы алфавита с массивами определений.

Я довольно новичок в Ruby, поэтому то, что у меня есть, выглядит действительно не элегантно, и я бьюсь над регулярным выражением строки в двоеточии, чтобы 3-я строка разделялась только в первом случае.

Спасибо!

Редактировать Вот что у меня так далеко

def self.build(lines)
    alphabet = Hash.new()

    lines.each do |line|
      strings = line.split(/:/)
      letter = strings[0][0,1].upcase
      alphabet[letter] = Array.new if alphabet[letter].nil?
      alphabet[letter] << strings[0]
      alphabet[letter] << strings[1..(strings.size-1)].join.strip
    end
    alphabet
  end

Ответы [ 2 ]

4 голосов
/ 21 января 2011

При условии, что вы используете raw_definitions:

sorted_defs = Hash.new{|hash, key| hash[key] = Array.new;}

raw_definitions.each do |d|
  d.match(/^([a-zA-Z])(.*?):(.*)$/)
  sorted_defs[$1.upcase]<<$1+$2
  sorted_defs[$1.upcase]<<$3.strip
end
2 голосов
/ 21 января 2011

Просто для удовольствия, вот чисто функциональная альтернатива:

defs = [
  "A definition 1: this is the definition text",
  "A definition 2: this is some other definition text",
  "B definition 3: this could be: the definition text"
]

hash = Hash[
  defs.group_by{ |s| s[0].to_sym }.map do |sym,strs|
    [ sym, strs.map{ |s| s[2..-1].split(/\s*:\s*/,2) }.flatten ]
  end
]

require 'pp'
pp hash
#=> {:A=>
#=>   ["definition 1",
#=>    "this is the definition text",
#=>    "definition 2",
#=>    "this is some other definition text"],
#=>  :B=>["definition 3", "this could be: the definition text"]}

И не совсем функциональный вариант с теми же результатами:

hash = defs.group_by{ |s| s[0].to_sym }.tap do |h|
  h.each do |sym,strs|
    h[sym] = strs.map{ |s| s[2..-1].split(/\s*:\s*/,2) }.flatten
  end 
end

Обратите внимание, чтоэти решения работают только в Ruby 1.9 из-за использования s[0].to_sym;для работы в 1.8.7 вы должны изменить это на s[0,1].to_sym.Чтобы первое решение заработало в 1.8.6, вам также необходимо заменить Hash[ xxx ] на Hash[ *xxx.flatten ]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...