需要一个`values_at_if`方法来映射ruby中的值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了需要一个`values_at_if`方法来映射ruby中的值相关的知识,希望对你有一定的参考价值。
我有两个相同大小的数组
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
我对它不满意。请让我知道一种有效的方法。
答案
更新
我能想到的最简单的解决方案是:
mapping.select.with_index {|_,i| response[i] == "Y"}
#=>["C", "D", "E"]
这将select
在mapping
中的所有元素,其中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
模块,还有很多其他方法可以完成此任务
另一答案
我会去
mapping.zip(response).select { |_, r| r == 'Y' }.map(&:first)
#=> ["C", "D", "E"]
另一答案
将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"]
请注意,如果response
由false
和true
s组成,它将节省内存,这也会使select块中的比较变得不必要。
另一答案
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
以上是关于需要一个`values_at_if`方法来映射ruby中的值的主要内容,如果未能解决你的问题,请参考以下文章