I have the following method:
Now sometimes I want the limit attribute to be ignored
Therefore the .take method would be ignored, at the moment I do not know how to do this gracefully. As setting to nil errors the code.
Any help appreciated - new to ruby.
def articlesByCategory( category, extensions = [ "md" ], limit = 3 )
# Check category is an array
if !category.kind_of?(Array)
category = [ category ]
end
# Create Return Array
ret = []
# Get the resources that are
sitemap.resources.select { |r| ( category & Array( r.data.category ) ).present? }.take( limit ).each do |a|
ret << a
end
# Return
ret
end
First, your code can be significantly refactored to do the same thing it’s doing now. There’s no need to do an each
to build an exact copy of the array, and we can apply Kernel#Array
to category
the same way your did to r.data.category
. Finally, any?
reads a bit better (IMO) than present?
, especially since the value cannot be nil
(only caveat is if nil
or false
is a valid category).
def articles_by_category category, limit = 3
category = Array(category)
sitemap.resources.select do |resource|
(Array(resource.data.category) & category).any?
end.take(limit)
end
We can easily pull the take
out into a conditional to get what you want:
def articles_by_category category, limit = 3
category = Array(category)
articles = sitemap.resources.select do |resource|
(Array(resource.data.category) & category).any?
end
limit ? articles.take(limit) : articles
end
It might, however, make sense to just get rid of the limit entirely within the method and impose it externally. This is much more functional and keeps your method from doing a lot of things (what does a limit have to do with getting articles by category? (this method doesn’t even get articles by category, it gets whatever resources is (presumably articles…) for a given category)).
def articles_by_category category
category = Array(category)
sitemap.resources.select do |resource|
(Array(resource.data.category) & category).any?
end
end
articles_by_category('My Category').take(3)
Note that if category will never be an array (which seems likely given its singular name) than you can further simplify your method to:
def articles_by_category category
sitemap.resources.select do |resource|
resource.data.category == category
end
end
(And of course add the limit
feature back in if so desired.)