Map an array modifying only elements matching a certain condition

前端 未结 9 2191
梦如初夏
梦如初夏 2021-02-05 09:07

In Ruby, what is the most expressive way to map an array in such a way that certain elements are modified and the others left untouched?

This is a straight-forw

9条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-05 09:23

    I agree that the map statement is good as it is. It's clear and simple,, and would easy for anyone to maintain.

    If you want something more complex, how about this?

    module Enumerable
      def enum_filter(&filter)
        FilteredEnumerator.new(self, &filter)
      end
      alias :on :enum_filter
      class FilteredEnumerator
        include Enumerable
        def initialize(enum, &filter)
          @enum, @filter = enum, filter
          if enum.respond_to?(:map!)
            def self.map!
              @enum.map! { |elt| @filter[elt] ? yield(elt) : elt }
            end
          end
        end
        def each
          @enum.each { |elt| yield(elt) if @filter[elt] }
        end
        def each_with_index
          @enum.each_with_index { |elt,index| yield(elt, index) if @filter[elt] } 
        end
        def map
          @enum.map { |elt| @filter[elt] ? yield(elt) : elt }
        end
        alias :and :enum_filter
        def or
          FilteredEnumerator.new(@enum) { |elt| @filter[elt] || yield(elt) }
        end
      end
    end
    
    %w{ a b c }.on { |x| x == 'b' }.map { |x| x + "!" } #=> [ 'a', 'b!', 'c' ]
    
    require 'set'
    Set.new(%w{ He likes dogs}).on { |x| x.length % 2 == 0 }.map! { |x| x.reverse } #=> #
    
    ('a'..'z').on { |x| x[0] % 6 == 0 }.or { |x| 'aeiouy'[x] }.to_a.join #=> "aefiloruxy"
    

提交回复
热议问题