class RuboCop::Cop::Performance::SelectMap

In Ruby 2.7, `Enumerable#filter_map` has been added.

This cop identifies places where `select.map` can be replaced by `filter_map`.

@example

# bad
ary.select(&:foo).map(&:bar)
ary.filter(&:foo).map(&:bar)

# good
ary.filter_map { |o| o.bar if o.foo }

Constants

MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/performance/select_map.rb, line 31
def on_send(node)
  return if (first_argument = node.first_argument) && !first_argument.block_pass_type?
  return unless (send_node = map_method_candidate(node))
  return unless send_node.method?(:map)

  map_method = send_node.parent&.block_type? ? send_node.parent : send_node

  range = offense_range(node, map_method)
  add_offense(range, message: format(MSG, method_name: node.method_name))
end

Private Instance Methods

map_method_candidate(node) click to toggle source
# File lib/rubocop/cop/performance/select_map.rb, line 44
def map_method_candidate(node)
  return unless (parent = node.parent)

  if parent.block_type? && parent.parent&.send_type?
    parent.parent
  elsif parent.send_type?
    parent
  end
end
offense_range(node, map_method) click to toggle source
# File lib/rubocop/cop/performance/select_map.rb, line 54
def offense_range(node, map_method)
  range_between(node.loc.selector.begin_pos, map_method.loc.expression.end_pos)
end