Выбор данных из структурированных данных, но элегантный функциональный способ - PullRequest
0 голосов
/ 05 февраля 2020

Видимо, моя способность мыслить функционально со временем угасла. У меня проблемы с выбором поднабора данных из набора данных. Я могу решить проблему хакерским императивным стилем, но я верю, что есть приятное функциональное решение, которое я, к сожалению, не могу найти.

Рассмотрим эту структуру данных (постарался не упростить ее за пределы юзабилити):

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, где ключ attrB равен "b2".

Мой хакерский путь был бы таким:

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}>}

, но я думаю, что будет одна строчка, использующая карту, фолд, молнию и уменьшение.

1 Ответ

0 голосов
/ 06 февраля 2020

Если вам нужен однострочник:

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 }

Хотя я не уверен, что вы пытаетесь сделать здесь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...