2013-08-21 41 views
1

給定名稱「Rigobert Song」如何返回「Rigobert S.」?有沒有更好的方法來返回名字和第一個名字?

名稱可以是Rigobert J. Song或只是Rigobert。我希望早些時候返回Rigobert S.,後者返回Rigobert

我寫了這個,它的工作原理。有更多的「Ruby方式」嗎?

def initials_for(user) 
    if user.name.split.size > 1 
    "#{user.name.split.first} #{user.name.split.last[0]}" 
    else 
    user.name 
    end 
end 
+4

這看起來很好 – apneadiving

+4

您的代碼不會給出您正在尋找的內容。提示:期間。 – sawa

+0

好的。謝謝。我以爲我多次使用'split'函數。感覺有點不對勁。 – user2630970

回答

4
"Rigobert J. Song" 
.gsub(/\s+.+\s+/, " ").sub(/(?<=\s\S).+/, ".") 
# => "Rigobert S." 

"Rigobert Song" 
.gsub(/\s+.+\s+/, " ").sub(/(?<=\s\S).+/, ".") 
# => "Rigobert S." 

"Rigobert" 
.gsub(/\s+.+\s+/, " ").sub(/(?<=\s\S).+/, ".") 
# => "Rigobert" 
+2

這很漂亮,很酷,謝謝,儘管我對於我的可讀性要低很多,因爲我對RegEx並不擅長。 – user2630970

+0

是的。它的工作原理非常棒,但不是很Ruby。 – screenmutt

+0

@screenmutt每個部分都有語義意義。 'gsub'刪除中間名部分,'sub'用其初始部分替換剩餘名稱部分。 – sawa

2

你不必拆分多次。你可以把它變成一個變量

def initials_for(user) 
    name_arry = user.name.split 
    name_arry.size > 1 ? "#{name_arry.first} #{name_arry.last[0]}" : user.name 
end 
+1

缺少來自@sawa的'Hint'。 – vee

1

這也可以。但我不知道這是否是一種「更好」的解決方案。

def initials_for(user) 
    parts = user.name.split 
    name = parts.first 
    name += " #{parts.last[0]}." if parts.length > 1 
    name 
end 
+0

我不會工作,如果parts.length不是> 1,它將返回false而不是名稱,你必須在末尾添加名稱 – MrYoshiji

+0

謝謝,我忘了最後一行。 – screenmutt

1

既然你標記它的Ruby-on-軌道,我假設你有present?可用...

def initials_for(full_name) 
    (first_name, *, last_name) = full_name.split 
    [first_name, name_initial(last_name)].reject(&:blank?).join(" ") 
end 

def name_initial(name) 
    if name.present? 
    "#{name[0]}." 
    else 
    "" 
    end 
end 

puts initials_for(user.name) 

首先,我分解出用戶的使用這個助手裏面,這是這個函數不需要知道的依賴關係。按照puts線的指示傳入字符串。

我由助手處理與一個週期爲幾其他指示第二初始..然後部件收集到一個數組,拒絕該空白部分,並用空間加入其中。

注意在分割的左側使用圖示和意圖揭示變量。如果你嘗試,你應該看到first_name總是有最左邊的名字,而last_name總是有最右邊的名字,或者如果只有一個名字存在,則爲零。

我用的拒絕這種模式,並加入了很多,與第一,去年,中,少女,共同姓名的變形處理的時候,留下一個可讀的名稱,沒有多餘的字符和這樣。

+0

當然,這在「John Doe II」上是失敗的。但這不符合你的規格。 :d – DGM

-1

編輯正確處理提問者的榜樣串

我喜歡用正則表達式。這允許第一個和/或最後一個名字中的任何字符。字符串中最多有兩個空格。

如果空格爲零,則所有字符均作爲第一個名稱放在捕獲組1中。

如果有一個空間,所述空間之前的字符被放置在捕獲組1作爲第一名稱和空間後的字符被放置在捕獲組3作爲姓氏。

如果有兩個空間,所述第一空間之前被放置在捕獲組1中的字符;捕獲組2中空格之間的字符;以及捕獲組3中第二個空格之後的字符。

#output 
Testing Rigobert Song 
Rigobert S. 
Testing Rigobert J. Song 
Rigobert S. 
Testing Rigobert J.Song 
Rigobert J. 
Testing RigobertJ.Song 
RigobertJ.Song 
Testing Rigobert 
Rigobert 


tests = [ "Rigobert Song", "Rigobert J. Song", "Rigobert J.Song", "RigobertJ.Song", "Rigobert", ] 
regex=\ 
/^([^ ]*) ?([^ ]*)?([^ ]+)?$/ 
#- - - - - - - - - - - - - - - 
# ^- - - - - - - - - - - - - - Match start of string here 
#^- -^- - - - - - - - - - Begin/End capture group 1 
# ^^^^^- - - - - - - - - - - Match 0 or more of any non-space character 
#   ^^ - - - - - - - - - Match zero or one literal space 
#   ^- - -^- - - - - Begin/End capture group 2 
#   ^^^^^ - - - - - - Match 0 or more non-space characters... 
#     ^- - - - - - ... with exactly one trailing space 
#     ^- - - - Make Capture group 2 optional (match 0 or 1) 
#     ^- -^- Begin/end capture group 3 
#      ^^^^^- - Match 1 or more non-space characters 
#       ^- Make capture group 3 optional 
#       ^Match end of string here 

tests.each do |str| 
    puts "Testing #{str}" 
    match = regex.match(str) 
    if(match != nil) 
    first = match[1] 
    middle = match[2] || "" 
    last = match[3] || "" 
    if(first != "" && last != "") 
     puts(first+" "+last[0].chr+".") # ruby 1.8 
     #puts(first+' '+last[0]+".")  # ruby 1.9 
    else 
     if(first != "" && last == "") 
     puts(first) 
     else 
     puts('Invalid name format') 
     end 
    end 
    else 
    puts('No regex match') 
    end 
end 
相關問題