Reputation: 238
I'm using Rails and have an array that I'm looking to control the output of.
In short, if a project with an ID exists in @projects
, then I don't want to output the corresponding part of the array, if that exists. So if a project with ID of 1 exists, then I don't want to output @array[1]
, even if that's present.
The following hardcoded case statement works successfully, to avoid outputting @array[1]
, @array[2]
and @array[3]
:
@array.each do |key, value|
case key when '1','2','3' then
next # Skip this array key
end
# Otherwise, do something else
end
But instead of hardcoding '1','2','3'
, I actually want these to be passed in dynamically, via ActiveRecord. i tried to build a string:
@projects_string = @projects.map {|element|
"'#{element.id}'"
}.join(',')
This outputs successfully as '1','2','3'
. But I can't figure out a way to pass this into the case statement. This fails to match:
@array.each do |key, value|
case key when "#{@projects_string}" then
next # Skip this array key
end
# Otherwise, do something else
end
Is there a way to achieve this using this method, or maybe a better way to achieve this using some of Rails' capabilities?
I did look through this answer, which seemed most relevant, but couldn't see how to implement it.
Upvotes: 0
Views: 507
Reputation: 2432
I feel like this depends on the type of collection you are dealing with: Array or ActiveRelation.
If they are just arrays and you want elements of @array
that aren't in @parent, you can just do:
@array - @parent
If they are both ActiveRecord objects, why not just filter out the @array
when it's created?
@array = Project.where.not(id: @projects.pluck(:id))
It seems inefficient (n^2) to have to scan a lookup array (@projects
) for each element in the collection you are iterating over.
Upvotes: 1
Reputation: 988
You can try the following:
@array = [1,2,3,4]
@projects = [2,3]
@array.each do |key|
case
when true === @projects.include?(key)
next
end
puts "Doing something else for #{key}"
end
Outputs:
Doing something else for 1
Doing something else for 4
Upvotes: 0
Reputation: 3721
You should not use string but use array and do like
@array = Array.new
@array = @projects.map{|arr| arr.id}
@array.each do |key, value|
if @array.include?(key)
#code to skip if project is included
else
#your code
end
end
Array can be used easily for comparisons than string
Upvotes: 1
Reputation: 5734
You can do it in this way as well.
@project_arr = @projects.map{|p| p.id.to_s}
@array.each do |key, value|
unless @project_arr.include?(key.to_s)
#YOUR CODE GOES HERE
else
# SKIP IT
end
end
Upvotes: 1