当前位置:  开发笔记 > 编程语言 > 正文

映射数组仅修改与特定条件匹配的元素

如何解决《映射数组仅修改与特定条件匹配的元素》经验,为你挑选了3个好方法。

在Ruby中,以某种方式映射数组的最具表现力的方式是什么?某些元素被修改而其他元素保持不变

这是一种直截了当的方式:

old_a = ["a", "b", "c"]                         # ["a", "b", "c"]
new_a = old_a.map { |x| (x=="b" ? x+"!" : x) }  # ["a", "b!", "c"]

如果不够的话,当然会省略"单独"的情况:

new_a = old_a.map { |x| x+"!" if x=="b" }       # [nil, "b!", nil]

我想要的是这样的:

new_a = old_a.map_modifying_only_elements_where (Proc.new {|x| x == "b"}) 
        do |y|
          y + "!"
        end
# ["a", "b!", "c"]

有没有一些很好的方法在Ruby中执行此操作(或者Rails有一些我还没有找到的方便方法)?


谢谢大家的回复.虽然你总是说服我最好只使用map三元运算符,但有些人发布了非常有趣的答案!



1> August Lille..:

因为数组是指针,所以这也有效:

a = ["hello", "to", "you", "dude"]
a.select {|i| i.length <= 3 }.each {|i| i << "!" }

puts a.inspect
# => ["hello", "to!", "you!", "dude"]

在循环中,确保使用改变对象的方法而不是创建新对象.例如,upcase!相比upcase.

确切的程序取决于您要实现的目标.用foo-bar的例子很难确定答案.



2> Ryan Bigg..:
old_a.map! { |a| a == "b" ? a + "!" : a }

=> ["a", "b!", "c"]

map!修改接收器到位,old_a现在返回的数组.



3> rampion..:

我同意地图声明是好的.它清晰简单,任何人都可以轻松维护.

如果你想要更复杂的东西,那怎么样?

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"


你已经把一行变成了三十多岁.我喜欢你的风格.
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有