ruby - 从结构化数据中选择数据,但优雅的功能方式
问题描述
显然,随着时间的推移,我思考功能的能力逐渐衰退。我在从数据集中选择子数据集时遇到问题。我可以用 hacky 命令式风格解决问题,但我相信,有一个很好的功能解决方案,不幸的是我找不到。
考虑这个数据结构(试图不简化它超出可用性):
class C
attr_reader :attrC
def initialize(base)
@attrC = { "c1" => base+10 , "c2" => base+20, "c3" => base+30}
end
end
class B
attr_reader :attrB
@@counter = 0
def initialize
@attrB = Hash.new
@attrB["b#{@@counter}"] = C.new(@@counter)
@@counter += 1
end
end
class A
attr_reader :attrA
def initialize
@attrA = { "a1" => B.new, "a2" => B.new, "a3" => B.new}
end
end
它被创建为a = A.new
. 完整的数据集将是
#<A: @attrA={"a1"=>#<B: @attrB={"b0"=>#<C: @attrC={"c1"=>10, "c2"=>20, "c3"=>30}>}>,
"a2"=>#<B: @attrB={"b1"=>#<C: @attrC={"c1"=>11, "c2"=>21, "c3"=>31}>}>,
"a3"=>#<B: @attrB={"b2"=>#<C: @attrC={"c1"=>12, "c2"=>22, "c3"=>32}>}>}>
这是受选择的。我只想检索B
whereattrB
的 key所在的那些实例"b2"
。
我的hacky方式是:
result = Array.new
A.new.attrA.each do |_,va|
result << va.attrB.select { |kb,_| kb == "b2" }
end
p result.reject { |a| a.empty?} [0]
这正是我想要的:
{"b2"=>#<C: @attrC={"c1"=>12, "c2"=>22, "c3"=>32}>}
但我相信会有一个使用 map、fold、zip 和 reduce 的单行。
解决方案
如果你想要一个单行:
a.attrA.values.select { |b| b.attrB.keys == %w(b2) }
这将返回B
. 在您的问题中,您得到的是attrB
值而不是B
. 如果这就是你想要的,那就是丑陋的reduce
:
a.attrA.values.reduce([]) { |memo, b| memo << b.attrB if b.attrB.keys == %w(b2) ; memo }
不过,我不确定你想在这里做什么?
推荐阅读
- c - C中的状态机实现
- redis - 在具有 redis-cli 密码的 redis 中删除带有模式的键
- selenium - 无法找到元素并单击按钮
- javascript - 在特定点流式传输 Mp3 文件
- c++ - 基于现有标签而不是二值图像使用 OpenCV 查找连接组件
- macos - 无法在 Mac Mac OS X - High Sierra 10.13.3 上运行的 Jmeter 中复制和粘贴
- r - 在R中使用条件删除txt文件中的几行
- regex - 从正则表达式中排除一些单词
- javascript - 按钮中的自动启动倒数计时器
- ios - 切换到另一个 VC Swift 后,iOS 动画无法正常工作