使用数组中的值扩展散列数组

spa*_*kle 0 ruby

我有这个数组

types = ['first', 'second', 'third']
Run Code Online (Sandbox Code Playgroud)

和这个哈希数组

data = [{query: "A"}, {query: "B"}, {query:"C", type: 'first'}]
Run Code Online (Sandbox Code Playgroud)

现在我必须“扩展”每个类型的每个数据哈希(如果不存在)。散列的所有现有键也必须复制(例如:查询)。所以最后的结果一定是:

results = [
  {query: "A", type: 'first'}, {query: "A", type: "second"}, {query: "A", type: "third"},
  {query: "B", type: 'first'}, {query: "B", type: "second"}, {query: "D", type: "third"},
  {query: "C", type: 'first'}, {query: "C", type: "second"}, {query: "C", type: "third"}
]
Run Code Online (Sandbox Code Playgroud)

数据数组对于性能问题来说非常大。

Ste*_*fan 5

您可以使用Array#product组合两个数组并Hash#merge添加:type键:

data.product(types).map { |h, t| h.merge(type: t) }
#=> [
#     {:query=>"A", :type=>"first"}, {:query=>"A", :type=>"second"}, {:query=>"A", :type=>"third"},
#     {:query=>"B", :type=>"first"}, {:query=>"B", :type=>"second"}, {:query=>"B", :type=>"third"},
#     {:query=>"C", :type=>"first"}, {:query=>"C", :type=>"second"}, {:query=>"C", :type=>"third"}
#   ]
Run Code Online (Sandbox Code Playgroud)

请注意,上述内容将用数组中:type的值替换现有值types。(:type每个哈希只能有一个)

如果您需要更复杂的逻辑,您可以传递一个块来merge处理现有/冲突的键,例如:

h = { query: 'C', type: 'first' }
t = 'third'

h.merge(type: t) { |h, v1, v2| v1 }         # preserve existing value
#=> {:query=>"C", :type=>"first"}

h.merge(type: t) { |h, v1, v2| [v1, v2] }   # put both values in an array
#=> {:query=>"C", :type=>["first", "third"]}
Run Code Online (Sandbox Code Playgroud)