使用所有同级键在 ruby 中填充或完成哈希

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

我有一个 Rails API,可以查询车辆并按不同属性进行计数和分组。当使用分组依据时,我想用零值填充响应。

这是一个简单的例子:

data = {
  AUDI: {
    Petrol: 379,
    Diesel: 326,
    Electric: 447
  },
  TESLA: {
    Electric: 779
  }
}

由于特斯拉没有任何汽油或柴油汽车,因此该密钥甚至不包含在响应中。我相信这是 postgres 中 group_by 的结果,它的结果中不包括零计数。

我正在尝试创建一个函数,可以用这些缺失的零值“填充”哈希值。

fill_hash(data)

应该回来

data = {
  AUDI: {
    Petrol: 379,
    Diesel: 326,
    Electric: 447
  },
  TESLA: {
    Petrol: 0,
    Diesel: 0,
    Electric: 779
  }
}

这个简单的案例我使用了 3 种方法:

def collect_keys(hash, keys = [])
  hash.each do |_, value|
    if value.is_a?(Hash)
      keys.concat(value.keys)
      collect_keys(value, keys)
    end
  end
  keys.uniq
end

def fill_missing_keys(hash, all_keys, default_value = 0)
  hash.each do |_, value|
    if value.is_a?(Hash)
      all_keys.each do |k|
        value[k] = default_value unless value.key?(k)
      end
      fill_missing_keys(value, all_keys, default_value)
    end
  end
  hash
end

def fill_hash(hash, default_value = 0)
  all_keys = collect_keys(hash)
  fill_missing_keys(hash, all_keys, default_value)
end

# Example usage:
hash = { a: { x: 1 }, b: { y: 1 } }
filled_hash = complete_hash(hash)
puts filled_hash
# Output should be: {:a=>{:x=>1, :y=>0}, :b=>{:y=>1, :x=>0}}

我的问题是哈希值可能会变得更加复杂。简单的情况仅按 2 个属性分组,但这里是我们按 3 个属性分组的示例。

{
  AUDI: {
    Deregistered: {
      Diesel: 56
    },
    Registered: {
      Petrol: 379,
      Diesel: 270,
      Electric: 447
    }
  },
  TESLA: {
    Registered: {
      Electric: 779
    }
  }
}

我想要的输出是:

{
  AUDI: {
    Deregistered: {
      Petrol: 0,
      Diesel: 56,
      Electric: 0
    },
    Registered: {
      Petrol: 379,
      Diesel: 270,
      Electric: 447
    }
  },
  TESLA: {
    Deregistered: {
      Petrol: 0,
      Diesel: 0,
      Electric: 0
    },
    Registered: {
      Petrol: 0,
      Diesel: 0,
      Electric: 779
    }
  }
}

例如。最后一层和倒数第二层都缺少键。

ruby algorithm hash transformation normalization
1个回答
0
投票

如何创建一个所有制造商都是其实例的类 VehicleCount,并在父级中将所有可能的计数设置为 0?

Class VehicleCount
  attr_accessor :Petrol, :Diesel, :Electric
  def initialize
        @:Petrol = @Diesel = @Electric = 0
    end
end

Class Vehicle
  attr_accessor :Registered, :Deregistered
  def initialize
    @Registered = VehicleCount.new
    @Deregistered = VehicleCount.new
  end
end

Audi = Vehicle.new
Audi.Deregistered.Diesel = 56
Audi.Registered.Petrol = 379
Audi.Registered.Diesel = 270
Audi.Registered.Electric = 447

类似这样的事情。

© www.soinside.com 2019 - 2024. All rights reserved.