创建名称助手,将名字和姓氏分开

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建名称助手,将名字和姓氏分开相关的知识,希望对你有一定的参考价值。

我正在寻找一些关于如何获取属性并通过方法处理它以返回不同内容的帮助。但我以前从未这样做过,我不确定从哪里开始。我想改变一个名字:字符串属性从“乔治华盛顿”或“约翰昆西亚当斯”变成名字只有“乔治”和“约翰”。

我想也许一个帮助方法是最好的,比如

users_helper.rb

def first_name

end

然后调用@ user.name.first_name,这最初是如何工作的?有人可以解释我下一步可以将@ user.name传递给方法吗?我见过这样的事情,但不太明白括号......

def first_name(name)
  puts name
end

有人可能会破坏rails / ruby​​这种类型的东西吗?非常感谢!

答案

括号(可选)括起参数列表。

def first_name(full_name)
  full_name.split(" ")[0]
end

这假设参数不是nil。

> puts first_name "Jimmy McKickems"
Jimmy
> puts first_name "Jeezy"
Jeezy

但这不是一个字符串方法,因为你现在假设:

@user.full_name.first_name # Bzzt.

代替:

first_name @user.name

这可以包含在模型类本身中:

class User < ActiveRecord
  # Extra stuff elided

  def first_name
    self.full_name.blank? ? "" : self.full_name.split(" ")[0]
  end
end

额外的代码检查名称是否为空或空格(blank?来自Rails)。如果是,则返回空字符串。如果不是,则将其拆分为空格并返回结果数组中的第一项。

另一答案

有些人有两个以上的名字,比如“John Clark Smith”。您可以选择将它们视为:

(1)first_name:“John”,last_name:“Smith”

  def first_name
    if name.split.count > 1
      name.split.first
    else
      name
    end
  end

  def last_name
    if name.split.count > 1
      name.split.last
    end
  end

(2)first_name:“John Clark”,last_name:“Smith”

  def first_name
    if name.split.count > 1
      name.split[0..-2].join(' ')
    else
      name
    end
  end

  def last_name
    if name.split.count > 1
      name.split.last
    end
  end

(3)first_name:“John”,last_name:“Clark Smith”

  def first_name
    name.split.first
  end

  def last_name
    if name.split.count > 1
      name.split[1..-1].join(' ')
    end
  end

上面的例子假设如果名称包含少于2个单词,那么它就是名字。

另一答案

如果您只想拆分一次并提供这两个部件,这个衬里将起作用:

last_name, first_name = *name.reverse.split(/s+/, 2).collect(&:reverse)

将最后一个单词作为姓氏,将其他所有内容作为名字。因此,如果有一个前缀,“Dr.”或将包含在名字中的中间名。显然,对于具有单独词语的姓氏,“戴高乐”它将无法工作,但处理更难(如果不是不可能的话)。

另一答案

对于你要求的语法(@user.name.first_name),Rails通过向基类型添加方法来做很多这种扩展,在你的例子中,你可以通过在String类上定义方法来实现。

class String
  def given; self.split(' ').first end
  def surname; self.split(' ').last end
end

"Phileas Fog".surname # 'fog'

执行此类操作的另一种方法是包装您希望扩展的类型,这样您就可以添加所需的所有疯狂语法,而不会污染更多基本类型,如字符串。

class ProperName < String
  def given; self.split(' ').first end
  def surname; self.split(' ').last end
end

class User
  def name
    ProperName.new(self.read_attribute(:name))
  end
end

u = User.new(:name => 'Phileas Fog')
u.name # 'Phileas Fog'
u.name.given # 'Phileas'
u.name.surname # 'Fog'
另一答案

正如Dave Newton的回答一样,这就是“姓氏”版本:

  def last_name
    self.full_name.blank? ? "" : self.full_name.split(" ")[-1]
  end
另一答案

使它变得简单

class User < ActiveRecord::Base

  def first_name
    self.name.split(" ")[0..-2].join(" ")
  end

  def last_name
    self.name.split(" ").last
  end
end

User.create name: "John M. Smith"
User.first.first_name
# => "John M."
User.first.last_name
# => "Smith"

谢谢

另一答案

使用Ruby的Array#pop

根据我的需要,我需要使用其中包含1,2,3或更多“名称”的全名,例如“AUSTIN”或“AUSTIN J GILLEY”。

The Helper Method

def split_full_name_into_first_name_and_last_name( full_name )
  name_array = full_name.split(' ')                     # ["AUSTIN", "J", "GILLEY"]

  if name_array.count > 1                   
    last_name  = name_array.pop                         # "GILLEY"
    first_name = name_array.join(' ')                   # "AUSTIN J"

  else                                      
    first_name = name_array.first           
    last_name  = nil
  end

  return [ first_name, last_name ]                      # ["AUSTIN J", "GILLEY"]
end

Using It

split_full_name_into_first_name_and_last_name( "AUSTIN J GILLEY" )
# => ["AUSTIN J", "GILLEY"]

split_full_name_into_first_name_and_last_name( "AUSTIN" )
# => ["AUSTIN", nil]

你可以轻松地分配first_namelast_name

first_name, last_name = split_full_name_into_first_name_and_last_name( "AUSTIN J GILLEY" )

first_name
# => "AUSTIN J"

last_name
# => "GILLEY"

您可以根据需要或想要的内容进行修改。

另一答案
def test_one(name)
  puts "#{name.inspect} => #{yield(name).inspect}"
end

def tests(&block)
  test_one nil, &block
  test_one "", &block
  test_one "First", &block
  test_one "First Last", &block
  test_one "First Middle Last", &block
  test_one "First Middle Middle2 Last", &block
end

puts "First name tests"
tests do |name|
  name.blank? ? "" : name.split(" ").tap{|a| a.pop if a.length > 1 }.join(" ")
end

puts "Last name tests"
tests do |name|
  name.blank? ? "" : (name.split(" ").tap{|a| a.shift }.last || "")
end

输出:

First name tests
nil => ""
"" => ""
"First" => "First"
"First Last" => "First"
"First Middle Last" => "First Middle"
"First Middle Middle2 Last" => "First Middle Middle2"

Last name tests

nil => ""
"" => ""
"First" => ""
"First Last" => "Last"
"First Middle Last" => "Last"
"First Middle Middle2 Last" => "Last"

以上是关于创建名称助手,将名字和姓氏分开的主要内容,如果未能解决你的问题,请参考以下文章

拆分一串名称并转置

如何在 Mailchimp 中仅获取成员字段名称(电子邮件地址、名字、姓氏)

从表中复制全名并将名字和姓氏插入新表的单独列中

sql MySQL:从完整的“名称”字段中提取姓氏和名字(对于Elgg)

如何在不同列上的名字和姓氏的不同行上搜索多个名称?

将泰国名字解析为第一个最后一个