需要一个`values_at_if`方法来映射ruby中的值

问题描述 投票:0回答:4

我有两个相同大小的数组

response = ["N","N","Y","Y","Y"]
mapping = ["A","B","C","D","E"]

我需要选择mapping中的元素,其中response中的对应值,即具有相同索引的元素,是"Y",如下所示

["C","D","E"]

它让我想起了values_at方法。我的解决方案如下

def values_at_if(response, mapping)
    result=[]
     response.each_index |k|
       if k=="Y"
         result << mapping[k]
       end
     end
   result
end

我对它不满意。请让我知道一种有效的方法。

arrays ruby
4个回答
4
投票

更新

我能想到的最简单的解决方案是:

mapping.select.with_index {|_,i| response[i] == "Y"}
#=>["C", "D", "E"]

这将selectmapping中的所有元素,其中response中的相应指数等于"Y"

TL; DR其他选项包括:

mapping.values_at(*response.each_with_index.select {|v,_| v == "Y"}.map(&:last))


mapping.zip(response).map {|k,v| k if v == "Y"}.compact

第一个使用每个索引将是

[["N",0],["N",1],["Y",2],["Y",3],["Y",4]]

然后我们选择第一个元素为“Y”的组,并映射索引以传递给values_at

第二个版本将映射和响应一起创建。

[["A", "N"], ["B", "N"], ["C", "Y"], ["D", "Y"], ["E", "Y"]]

然后仅在第二个元素为“Y”时映射第一个元素。 compact从映射中删除nil值。

如果您查看Enumerable模块,还有很多其他方法可以完成此任务


3
投票

我会去

mapping.zip(response).select { |_, r| r == 'Y' }.map(&:first)
#=> ["C", "D", "E"]

3
投票

response转换为枚举器; each没有挡住那样做。然后在选择块中使用它。如果块返回true,则选择该项:

response = ["N","N","Y","Y","Y"]
mapping  = ["A","B","C","D","E"]

enum_resp = response.each
mapping.select{ enum_resp.next == "Y" } # =>["C", "D", "E"]

请注意,如果responsefalsetrues组成,它将节省内存,这也会使select块中的比较变得不必要。


1
投票
response.each_with_object([]).with_index do |(v, arr), i|
  arr << mapping[i] if v == 'Y' 
end

要么

mapping.each_with_object([]).with_index do |(v, arr), i|
  arr << v if response[i] == 'Y' 
end
© www.soinside.com 2019 - 2024. All rights reserved.