在Ruby中如何将一个数组的特定元素映射到另一个数组?

3

我有一个像这样的数组:

[1,2,3,2,4,5,3,7,8]

我希望将它们映射到其他元素2 => 'b',3 => 'a'

[1,'b','a','b',4,5,'a',7,8]

有哪些策略可以做到这一点?
3个回答

10
arr = [1,2,3,2,4,5,3,7,8]
h = { 2=>'b', 3=>'a' }

h.default_proc = ->(_,k) { k }
h.values_at(*arr)
  #=> [1, "b", "a", "b", 4, 5, "a", 7, 8] 

2
我喜欢你将问题内外翻转的方式。 - mu is too short
相当优雅的方法。 - Aleksei Matiushkin
@CarySwoveland:我必须说你在Ruby方面非常有创意。总是能提出整洁的解决方案。默认处理程序加1。 - Gagan Gami
2
谢谢,@Gagan。如果我可以提供一个小建议:处理那些有趣但已经陈旧的问题。当我回答这个问题时,它还很新鲜,但我经常花时间回答陈旧的问题。昨天我回答了一个2008年提出的问题(对我来说非常陈旧)。原因是,如果一个问题已经陈旧,所有明显的解决方案都已经被提出,所以你必须有创意才能想出一个好的、原创的答案。 - Cary Swoveland
尽管我很喜欢你想要教授人们 Ruby 的酷炫功能,但当我查看生产代码时,@falsetru 的答案是我希望看到的答案。 - ndnenkov
显示剩余3条评论

6

使用 Hash 作为映射,使用 Array#map 获取一个新的映射数组:

mapping = {2 => 'b', 3 => 'a' }
[1,2,3,2,4,5,3,7,8].map { |x| mapping.fetch(x, x) }
=> [1, "b", "a", "b", 4, 5, "a", 7, 8]

1

这里有另一种可能的解决方案,类似于@falsetru的答案

mapping = Hash.new {|_, v| v }.merge(2 => 'b', 3 => 'a')
[1, 2, 3, 2, 4, 5, 3, 7, 8].map(&mapping.method(:[]))
# => [1, 'b', 'a', 'b', 4, 5, 'a', 7, 8]

在 Ruby 问题跟踪器上的 Feature #11262 – 让更多对象像 "Functions" 一样行为 中,我建议 Hash 应该像从键到值的函数一样运作,即它们应该实现 callto_proc,这将允许您直接将 mapping 作为转换函数传递给 map

[1, 2, 3, 2, 4, 5, 3, 7, 8].map(&mapping)
# => [1, 'b', 'a', 'b', 4, 5, 'a', 7, 8]

在我的建议得到实现之前(考虑到两个月内没有人看过它,这可能永远不会发生),您需要使用此猴子补丁才能使其正常工作:

module HashAsFunction
  refine Hash do
    alias_method :call, :[]

    def to_proc
      method(:call).to_proc
    end
  end
end

using HashAsFunction

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接