我尝试做的想法是将同义词符号聚集到相同的值,而不必一遍又一遍地重新定义相同的值。基本上就是这样:
fruits = { orange: "Citrus", grapefruit: "Citrus", tangerine: "Citrus" }如下所示:
fruits = { orange:, grapefruit:, tangerine: => "Citrus" }完成这一任务的正确语法是什么?
谢谢
发布于 2021-01-28 05:57:30
使用散列,以便使用水果名称访问水果的类型。例如:
fruits = %i{ orange grapefruit tangerine apple }
citrus_fruits = %i{ orange grapefruit tangerine }
fruit_type = citrus_fruits.zip([:citrus] * citrus_fruits.length).to_h
fruit_type[:apple] = :rosaceae
puts fruit_type
# {:orange=>:citrus, :grapefruit=>:citrus, :tangerine=>:citrus, :apple=>:rosaceae}发布于 2021-01-28 05:57:36
按值对键进行分组;可选地转换返回值
在Ruby中,Symbol是一个核心类,它为事物提供标识符,并且在运行时符号永远不会重复。抛开它们在内部的使用方式不谈,在代码中使用符号的最常见用例是在Hash中定义键。您可以使用其他类型的键,但符号的属性使其作为哈希键特别有用。
有了这种方法,看起来您正在尝试对类似的Hash值进行分组,但不清楚您希望如何使用这种分组。有不止一种方法可以做到这一点,所以我只选择其中一种作为示例。
给定一个类似这样的Hash:
produce =
{
:orange => "citrus",
:grapefruit => "citrus",
:tangerine => "citrus",
:raspberry => "berry",
:strawberry => "berry",
:canteloupe => "melon",
:honeydew => "melon"
}您可以使用Hash#group_by (继承自Enumerable)来按值对Hash进行快速排序。例如,使用Ruby 3.0.0:
produce.group_by { _2 }
#=>
{"citrus"=>
[[:orange, "citrus"], [:grapefruit, "citrus"], [:tangerine, "citrus"]],
"berry"=>[[:raspberry, "berry"], [:strawberry, "berry"]],
"melon"=>[[:canteloupe, "melon"], [:honeydew, "melon"]]}这将返回一个按唯一值分组的Hash,但您可能更喜欢在嵌套的Array对象中丢弃produce类型。您可以像这样使用Hash#transform_values完成此操作:
produce.group_by { _2 }.transform_values { _1.map &:first }
#=>
{"citrus"=>[:orange, :grapefruit, :tangerine],
"berry"=>[:raspberry, :strawberry],
"melon"=>[:canteloupe, :honeydew]}无论哪种方式,要点都是哈希键与一个几乎可以属于任何类的值相关联,因此您可以检查每个值的内容,以确定它们是否属于您想要的分组(当前由您的键定义)。
您当前的数据结构对于检索产品类型(例如,柑橘类水果)来说并不是真正优化的,但它确实可以做到。但是,您可能需要重新考虑是否具有适合您想要访问或操作数据的方式的数据结构。您的里程数肯定会有所不同。
发布于 2021-01-28 06:37:19
你对主板和蓝图的评论表明你得到了类似这样的东西
h = { :mb1=>:bp3, :mb_2=>:bp1, :mb3=>:bp3, :mb4=>:bp2, :mb5=>:bp1 }并希望生成散列
{ :bp3=>[:mb1, :mb3], :bp1=>[:mb_2, :mb5], :bp2=>[:mb4] }有很多方法可以做到这一点,其中之一是:
h.each_with_object({}) { |(k,v),g| (g[v] ||= []) << k }请参阅Enumerable#each_with_object,要了解我为什么要编写块变量|(k,v),g|,请参阅array decomposition。
这是以下代码的精简翻译(我使用了三个puts语句来显示正在执行的计算):
g = {}
h.each do |key_value_pair|
k, v = key_value_pair
puts "\nkey_value_pair = #{key_value_pair}, k = #{k}, v = #{v}"
puts "g[#{v}] set to [] because g[#{v}] == nil" if g[v].nil?
g[v] = [] if g[v].nil?
g[v] << k
puts "g after g[#{v}] << #{g}"
end
#=> {:mb1=>:bp3, :mb_2=>:bp1, :mb3=>:bp3, :mb4=>:bp2, :mb5=>:bp1}将显示以下内容:
key_value_pair = [:mb1, :bp3], k = mb1, v = bp3
g[bp3] set to [] because g[bp3] == nil
g after g[bp3] << {:bp3=>[:mb1]}
key_value_pair = [:mb_2, :bp1], k = mb_2, v = bp1
g[bp1] set to [] because g[bp1] == nil
g after g[bp1] << {:bp3=>[:mb1], :bp1=>[:mb_2]}
key_value_pair = [:mb3, :bp3], k = mb3, v = bp3
g after g[bp3] << {:bp3=>[:mb1, :mb3], :bp1=>[:mb_2]}
key_value_pair = [:mb4, :bp2], k = mb4, v = bp2
g[bp2] set to [] because g[bp2] == nil
g after g[bp2] << {:bp3=>[:mb1, :mb3], :bp1=>[:mb_2], :bp2=>[:mb4]}
key_value_pair = [:mb5, :bp1], k = mb5, v = bp1
g after g[bp1] << {:bp3=>[:mb1, :mb3], :bp1=>[:mb_2, :mb5], :bp2=>[:mb4]}https://stackoverflow.com/questions/65926954
复制相似问题