Reputation: 2900
I've got response which hash and 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"}},
]
What I need is to pull the name for each hash['actors']
and convert it to the email address. The thing is I need to skip names which are defined as EXCLUDED_NAMES
EXCLUDED_NAMES = %w[
chris.sth
removed1258986304
john.doe
other.names
].freeze
private_constant :DEFAULT_EXCLUDED_NAMES
I was trying to something like below but still get all 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
Upvotes: 0
Views: 867
Reputation: 16012
If dev_role['actors']
is this:
[
{"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"}},
]
then it is certain that user
in each
block would be a Hash
object:
{
"id"=>123,
"displayName"=>"John Doe",
"type"=>"atlassian-user-role-actor",
"name"=>"john.doe",
"actorUser"=>{"accountId"=>"some_id"}
}
So, doing user["name"]
, should produce: "john.doe"
.
Now, that we have an exclusion list EXCLUDED_NAMES
we could use include?
like so on it:
EXCLUDED_NAMES.include?(user["name"])
=> # true if the name is in the EXCLUDED_NAMES
So, all you need is a small change in your code to fix the condition:
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
There is one problem though, the user.delete
would not work as it expects an argument that is supposed to be a key to the hash object.
This can be fixed through by using reject
or select
(changing to reject
as it reads better):
def setup_email
dev_role['actors'].reject do |user|
EXCLUDED_NAMES.include?(user["name"])
end.map{ |user| user["name"] }
end
The nature of the method seems to be returning an array/list, so I would insist that the name of such methods should be plural: setup_emails
.
Upvotes: 1
Reputation: 33
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
Upvotes: 0
Reputation: 21130
I'd create a lookup hash based upon the the actor name. Then retrieve the values that are not in EXCLUDED_NAMES
.
When actors can contain duplicate names:
actors = dev_role['actors'].group_by { |actor| actor['name'] }
actors = actors.values_at(*actors.keys - EXCLUDED_NAMES).flatten(1)
When actors can't contain duplicate names:
actors = dev_role['actors'].to_h { |actor| [actor['name'], actor] }
actors = actors.values_at(*actors.keys - EXCLUDED_NAMES)
Then:
emails = actors.map { |actor| "#{actor['name']}@example.com" }
You could also solve this with an Array#reject
/Array#map
combination:
emails = dev_role['actors']
.reject { |actor| EXCLUDED_NAMES.include?(actor['name']) }
.map { |actor| "#{actor['name']}@example.com" }
The above might be slower when using a large EXCLUDED_NAMES
array.
Upvotes: 0
Reputation: 131
You can get an array of valid emails with:
emails = dev_role['actors'].map do |user|
"#{user['name']}@example.com" unless EXCLUDED_NAMES.include?(user['name'])
end
Array will only contain '[email protected]'
Upvotes: 2