Ruby 从哈希数组中排除特定数据
Ruby exclude specific data from array of hashes
我得到了哈希和哈希数组的响应:
"id"=>67547,
"description"=>"project",
"actors"=>
[
{"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>456,
"displayName"=>"Chris Sth",
"type"=>"atlassian-user-role-actor",
"name"=>"chris.sth",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>789,
"displayName"=>"Testing Name",
"type"=>"atlassian-user-role-actor",
"name"=>"testing.name",
"actorUser"=>{"accountId"=>"some_id"}},
]
我需要的是提取每个 hash['actors']
的名称并将其转换为电子邮件地址。问题是我需要跳过定义为 EXCLUDED_NAMES
的名称
EXCLUDED_NAMES = %w[
chris.sth
removed1258986304
john.doe
other.names
].freeze
private_constant :DEFAULT_EXCLUDED_NAMES
我正在尝试类似下面的内容,但仍然得到所有名称:
def setup_email
dev_role['actors'].map do |user|
if user.include?(EXCLUDED_NAMES)
user.delete
else
"#{user['name']}@example.com"
end
end
end
如果dev_role['actors']
是这样的:
[
{"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>456,
"displayName"=>"Chris Sth",
"type"=>"atlassian-user-role-actor",
"name"=>"chris.sth",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>789,
"displayName"=>"Testing Name",
"type"=>"atlassian-user-role-actor",
"name"=>"testing.name",
"actorUser"=>{"accountId"=>"some_id"}},
]
那么可以肯定each
块中的user
是一个Hash
对象:
{
"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}
}
所以,做 user["name"]
,应该产生:"john.doe"
。
现在,我们有了一个排除列表 EXCLUDED_NAMES
,我们可以像这样使用 include?
:
EXCLUDED_NAMES.include?(user["name"])
=> # true if the name is in the EXCLUDED_NAMES
因此,您只需要对代码进行少量更改即可解决此问题:
def setup_email
dev_role['actors'].map do |user|
if EXCLUDED_NAMES.include?(user["name"])
user.delete
else
"#{user['name']}@example.com"
end
end
end
但是有一个问题,user.delete
无法工作,因为它需要一个应该是散列对象键的参数。
这可以通过使用 reject
或 select
来解决(更改为 reject
因为它看起来更好):
def setup_email
dev_role['actors'].reject do |user|
EXCLUDED_NAMES.include?(user["name"])
end.map{ |user| user["name"] }
end
方法的本质似乎是返回一个array/list,所以我坚持认为这种方法的名称应该是复数:setup_emails
.
您可以获得一组有效的电子邮件:
emails = dev_role['actors'].map do |user|
"#{user['name']}@example.com" unless EXCLUDED_NAMES.include?(user['name'])
end
数组将只包含'testing.name@example.com'
我会根据演员姓名创建查找哈希。然后检索不在 EXCLUDED_NAMES
.
中的值
当演员可以包含重名时:
actors = dev_role['actors'].group_by { |actor| actor['name'] }
actors = actors.values_at(*actors.keys - EXCLUDED_NAMES).flatten(1)
当演员不能包含重名时:
actors = dev_role['actors'].to_h { |actor| [actor['name'], actor] }
actors = actors.values_at(*actors.keys - EXCLUDED_NAMES)
然后:
emails = actors.map { |actor| "#{actor['name']}@example.com" }
您也可以使用 Array#reject
/Array#map
组合来解决此问题:
emails = dev_role['actors']
.reject { |actor| EXCLUDED_NAMES.include?(actor['name']) }
.map { |actor| "#{actor['name']}@example.com" }
使用较大的 EXCLUDED_NAMES
数组时,上面的代码可能会变慢。
dev_role=dev_role.to_hash
actors=dev_role["actors"]
for each_actor in actors
if EXCLUDED_NAMES.include?(each_actor["name"])==false
p "#{each_actor['name']}@example.com"
end
end
我得到了哈希和哈希数组的响应:
"id"=>67547,
"description"=>"project",
"actors"=>
[
{"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>456,
"displayName"=>"Chris Sth",
"type"=>"atlassian-user-role-actor",
"name"=>"chris.sth",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>789,
"displayName"=>"Testing Name",
"type"=>"atlassian-user-role-actor",
"name"=>"testing.name",
"actorUser"=>{"accountId"=>"some_id"}},
]
我需要的是提取每个 hash['actors']
的名称并将其转换为电子邮件地址。问题是我需要跳过定义为 EXCLUDED_NAMES
EXCLUDED_NAMES = %w[
chris.sth
removed1258986304
john.doe
other.names
].freeze
private_constant :DEFAULT_EXCLUDED_NAMES
我正在尝试类似下面的内容,但仍然得到所有名称:
def setup_email
dev_role['actors'].map do |user|
if user.include?(EXCLUDED_NAMES)
user.delete
else
"#{user['name']}@example.com"
end
end
end
如果dev_role['actors']
是这样的:
[
{"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>456,
"displayName"=>"Chris Sth",
"type"=>"atlassian-user-role-actor",
"name"=>"chris.sth",
"actorUser"=>{"accountId"=>"some_id"}},
{"id"=>789,
"displayName"=>"Testing Name",
"type"=>"atlassian-user-role-actor",
"name"=>"testing.name",
"actorUser"=>{"accountId"=>"some_id"}},
]
那么可以肯定each
块中的user
是一个Hash
对象:
{
"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}
}
所以,做 user["name"]
,应该产生:"john.doe"
。
现在,我们有了一个排除列表 EXCLUDED_NAMES
,我们可以像这样使用 include?
:
EXCLUDED_NAMES.include?(user["name"])
=> # true if the name is in the EXCLUDED_NAMES
因此,您只需要对代码进行少量更改即可解决此问题:
def setup_email
dev_role['actors'].map do |user|
if EXCLUDED_NAMES.include?(user["name"])
user.delete
else
"#{user['name']}@example.com"
end
end
end
但是有一个问题,user.delete
无法工作,因为它需要一个应该是散列对象键的参数。
这可以通过使用 reject
或 select
来解决(更改为 reject
因为它看起来更好):
def setup_email
dev_role['actors'].reject do |user|
EXCLUDED_NAMES.include?(user["name"])
end.map{ |user| user["name"] }
end
方法的本质似乎是返回一个array/list,所以我坚持认为这种方法的名称应该是复数:setup_emails
.
您可以获得一组有效的电子邮件:
emails = dev_role['actors'].map do |user|
"#{user['name']}@example.com" unless EXCLUDED_NAMES.include?(user['name'])
end
数组将只包含'testing.name@example.com'
我会根据演员姓名创建查找哈希。然后检索不在 EXCLUDED_NAMES
.
当演员可以包含重名时:
actors = dev_role['actors'].group_by { |actor| actor['name'] }
actors = actors.values_at(*actors.keys - EXCLUDED_NAMES).flatten(1)
当演员不能包含重名时:
actors = dev_role['actors'].to_h { |actor| [actor['name'], actor] }
actors = actors.values_at(*actors.keys - EXCLUDED_NAMES)
然后:
emails = actors.map { |actor| "#{actor['name']}@example.com" }
您也可以使用 Array#reject
/Array#map
组合来解决此问题:
emails = dev_role['actors']
.reject { |actor| EXCLUDED_NAMES.include?(actor['name']) }
.map { |actor| "#{actor['name']}@example.com" }
使用较大的 EXCLUDED_NAMES
数组时,上面的代码可能会变慢。
dev_role=dev_role.to_hash
actors=dev_role["actors"]
for each_actor in actors
if EXCLUDED_NAMES.include?(each_actor["name"])==false
p "#{each_actor['name']}@example.com"
end
end