【问题标题】:Crystal: how to increase the number of types an array can hold after instantiationCrystal:如何增加实例化后数组可以容纳的类型数量
【发布时间】:2018-12-06 10:47:11
【问题描述】:

我正在构建一个数据表。起初,这个表的行最容易被键/值填充,所以我使用哈希

a = Hash(Int32, Symbol).new
a[1] = :one

完成后,使用数组会更方便(例如,我需要对数据进行排序)。很简单:

a.to_a # => [{1, :one}]

但现在我发现,如果我可以在该数组中存储另一种数据类型,例如字符串,那么为了让我的格式化程序正常工作(多页表,使用乳胶),事情会更有意义。但为时已晚!数组的类型是固定的;它不会接受字符串。

a << "str" # => ERROR!

到目前为止我提出的解决方案似乎不是很优雅:

a = Hash(Int32, Symbol).new
a[1] = :one
arr = Array(String | Tuple(Int32, Symbol)).new
a.each do |k,v|
  arr << {k,v}
end
arr << "str" # no problem now

还有更“水晶”/优雅的方式吗?

【问题讨论】:

  • 首先使用Hash 是否有特定原因?如果您不需要查找或重复检查,键值对也可以直接存储在数组中。这样就完全避免了转换为数组的问题。
  • 最好有一个collectto_a(target) 方法,它可以简单地将所有元素添加到给定的目标。这样你就可以做到a.to_a([] of String | Other)
  • @JohannesMüller 是的,就我而言,我需要按键值查找来填充数据。它是一维键控的二维数据,所以我必须遍历列,按键填充,然后遍历行并按键填充。哈希是完美的工具。

标签: crystal-lang


【解决方案1】:

只需将to_aas 一起使用,它就可以用于转换为文档所称的“更大”类型

a = Hash(Int32, Symbol).new
a[1] = :one
arr = a.to_a.map { |x| x.as(String | Tuple(Int32, Symbol)) }
arr << "str" # [{1, :one}, "str"]

【讨论】:

  • 您最初的解决方案已经比这更优雅了。在这里,您创建一个数组只是为了立即将其丢弃,并在此过程中对所有项目进行两次迭代。这既不高效也不优雅。
  • 哦,我明白你的意思了,这个想法可能代码行数更少,但to_a 是浪费。感谢您指出这一点!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 2013-03-09
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
相关资源
最近更新 更多