ruby-on-rails - 如何使用 ruby 格式化对象数组?
问题描述
我对如何格式化这个对象数组有点迷茫。
初始数组:
cars = [{model: 'nissan', type: 'wingroad'},{model: 'nissan', type: 'sunny'},{model: 'nissan', type: 'terrano'},{model: 'toyota', type: 'hilux'}]
预期输出:
formatted_cars = [{name: 'nissan', value: ['wingroad', 'sunny', 'terrano']}, {name: 'toyota', value: ['hilux']
我会映射结果并应用注入,然后对该格式化数组应用一些巧妙的合并技术。或者还有其他方法可以解决吗?
我是 ruby 新手,希望得到任何帮助,谢谢 :)
解决方案
有很多方法可以做到这一点。这是一个;
cars = [
{model: 'nissan', type: 'wingroad'},
{model: 'nissan', type: 'sunny'},
{model: 'nissan', type: 'terrano'},
{model: 'toyota', type: 'hilux'}
]
cars
.group_by { |car| car[:model] }
.map { |model, cars| {name: model, value: cars.map { |car| car[:type] }} }
...但是,您为什么以这种奇怪的数据格式开始,并打算以另一种奇怪的数据格式结束?(通过“奇数”,我基本上是指依靠数组的哈希数组来存储数据。)
这可能有一个很好的理由(例如与第 3 方 API 集成),但除此之外,我建议以某种方式使其更加面向对象并使用类来定义汽车的品牌/型号。例如,也许是这样的:
# e.g. Nissan
class CarMake
attr_reader :name, :models
def initialize(name)
@name = name
@models = []
end
def add_model(name)
model = CarModel.new(name)
@models << model
model.make = self
end
end
# e.g. WingRoad
class CarModel
attr_reader :name
attr_accessor :make
def initialize(name)
@name = name
end
end
# Assuming we still need to start with this data structure!
cars = [
{model: 'nissan', type: 'wingroad'},
{model: 'nissan', type: 'sunny'},
{model: 'nissan', type: 'terrano'},
{model: 'toyota', type: 'hilux'}
]
car_makes = {}
cars.each do |car|
car_makes[car[:model]] ||= CarMake.new(car[:model])
car_makes[car[:model]].add_model(car[:type])
end
这只是组织代码的许多可能方法之一,虽然起初理解起来可能有点复杂,但生成的数据结构更有用:
car_makes
=> {"nissan"=>
#<CarMake:0x00007ff2ee44ad20
@models=
[#<CarModel:0x00007ff2ee44aca8 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="wingroad">,
#<CarModel:0x00007ff2ee44ac80 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="sunny">,
#<CarModel:0x00007ff2ee44ac58 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="terrano">],
@name="nissan">,
"toyota"=>#<CarMake:0x00007ff2ee44ac30 @models=[#<CarModel:0x00007ff2ee44ab68 @make=#<CarMake:0x00007ff2ee44ac30 ...>, @name="hilux">], @name="toyota">}
car_makes['nissan'].models
=> [#<CarModel:0x00007ff2ee44aca8 @make=#<CarMake:0x00007ff2ee44ad20 @models=[...], @name="nissan">, @name="wingroad">,
#<CarModel:0x00007ff2ee44ac80 @make=#<CarMake:0x00007ff2ee44ad20 @models=[...], @name="nissan">, @name="sunny">,
#<CarModel:0x00007ff2ee44ac58 @make=#<CarMake:0x00007ff2ee44ad20 @models=[...], @name="nissan">, @name="terrano">]
car_makes['nissan'].models.first
=> #<CarModel:0x00007ff2ee44aca8
@make=
#<CarMake:0x00007ff2ee44ad20
@models=
[#<CarModel:0x00007ff2ee44aca8 ...>,
#<CarModel:0x00007ff2ee44ac80 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="sunny">,
#<CarModel:0x00007ff2ee44ac58 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="terrano">],
@name="nissan">,
@name="wingroad">
car_makes['nissan'].models.first.make
=> #<CarMake:0x00007ff2ee44ad20
@models=
[#<CarModel:0x00007ff2ee44aca8 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="wingroad">,
#<CarModel:0x00007ff2ee44ac80 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="sunny">,
#<CarModel:0x00007ff2ee44ac58 @make=#<CarMake:0x00007ff2ee44ad20 ...>, @name="terrano">],
@name="nissan">
...等等。我们现在有一个结构化的数据,而不是随意的(并且命名错误!)数组和散列的混合,这些混合操作起来很麻烦。
推荐阅读
- swift - 来自 UIPickerView 的索引行 didSelectRow 选择
- r - 用 case_when 在 R 中查看列名末尾的数字大于另一个列名末尾的数字
- swift - Swift UI - 如何制作图像网格?
- javascript - 如何在 JavaScript 中为 CSS 属性动态使用函数参数
- html - html代码中的Radio类型和复选框类型有什么区别?
- javascript - JSX 上下文何时开始?
- angular - NRWL NX 导入库错误 TS2307:找不到模块“@eduboard/interfaces”
- kubernetes - 如何在 gitlab ci 中修复 k8s 命名空间权限
- javascript - 我将如何通过网络应用程序编译代码?
- java - 对固定长度的字符串进行排序