我有两个散列数组,它们由一组共同的键关联:
[
{0=>"pmet-add-install-module-timings.patch"},
{1=>"pmet-change-sample-data-load-order.patch"},
{2=>"pmet-configurable-recurring.patch"},
{3=>"pmet-consumers-run-staggered-by-sleep.patch"},
{4=>"pmet-dynamic-block-segment-display.patch"},
{5=>"pmet-fix-admin-label-word-breaking.patch"},
{6=>"pmet-fix-invalid-module-dependencies.patch"},
{7=>"pmet-fix-invalid-sample-data-module-dependencies.patch"},
{8=>"pmet-fix-module-loader-algorithm.patch"},
{9=>"pmet-fix-sample-data-code-generator.patch"},
{10=>"pmet-remove-id-requirement-from-layout-update-file.patch"},
{11=>"pmet-specify-store-id-for-order.patch"},
{12=>"pmet-staging-preview-js-fix.patch"},
{13=>"pmet-stop-catching-sample-data-errrors-during-install.patch"},
{14=>"pmet-visitor-segment.patch"}
]
[
{0=>"magento2-base"},
{1=>"magento/module-sample-data"},
{2=>"magento/module-configurable-sample-data"},
{3=>"magento/module-message-queue"},
{4=>"magento/module-banner"},
{5=>"magento/theme-adminhtml-backend"},
{6=>"magento/module-staging"},
{7=>"magento/module-gift-registry-sample-data"},
{8=>"magento2-base"},
{9=>"magento/module-downloadable-sample-data"},
{10=>"magento/module-catalog"},
{11=>"magento/module-sales-sample-data"},
{12=>"magento/module-staging"},
{13=>"magento2-base"},
{14=>"magento/module-customer"}
]
注意,这些数组中的每个哈希具有相同的索引集,并且第二个数组在键0
,8
和13
以及6
中具有duplicate值]和12
。
我的目标是将来自这两个数据集的值缝合在一起,成为一组嵌套的哈希。数组2中任何有重复值的地方,我都需要从数组1中收集其关联值,并将它们包括在嵌套哈希中。例如,从数组2中获取magento2-base
值,从数组1中获取键相关的值。ruby代码中的哈希结构如下所示:
hash = {
"magento2-base" => [
{0 => "m2-hotfixes/pmet-add-install-module-timings.patch"},
{8 => "m2-hotfixes/pmet-fix-module-loader-algorithm.patch"},
{13 => "m2-hotfixes/pmet-stop-catching-sample-data-errrors-during-install.patch"}
]
}
对于来自数组2的任何其他重复值也是如此。因此,例如,magento/module-staging
为:
hash = {
"magento/module-staging" => [
{6 => "pmet-fix-invalid-module-dependencies.patch"},
{12 => "pmet-staging-preview-js-fix.patch"}
]
}
因此,将这些需求结合在一起的结果哈希的较大摘录将如下所示:
hash = {
"magento2-base" =>
[
{0 => "m2-hotfixes/pmet-add-install-module-timings.patch"},
{8 => "m2-hotfixes/pmet-fix-module-loader-algorithm.patch"},
{13 => "m2-hotfixes/pmet-stop-catching-sample-data-errrors-during-install.patch"}
],
"magento/module-sample-data" =>
{0 => "pmet-change-sample-data-load-order.patch"},
"magento/module-configurable-sample-data" =>
{2 => "pmet-configurable-recurring.patch"},
"magento/module-message-queue" =>
{3 => "pmet-consumers-run-staggered-by-sleep.patch"}
"magento/module-staging" =>
[
{6 => "pmet-fix-invalid-module-dependencies.patch"},
{12 => "pmet-staging-preview-js-fix.patch"}
],
...
}
[不幸的是,我的红宝石技能很初级,所以我无法利用语言的魔力。此刻,我陷入了一个嵌套循环,该循环将两个数组组合在一起以链接各个键。从那里,我尝试从数组2中提取重复项,并认为我需要既维护数组2中重复值的数组,又维护数组1中与它们相关的值的数组。然后,我想使用一些数组合并魔术将它们重新组合在一起。这是我所拥有的:
found_modules_array = []
duplicate_modules_array = []
duplicate_module_hash = {}
file_collection_array = []
modules_array.each do |module_hash|
module_hash.each do |module_hash_key, module_hash_value|
files_array.each do |file_hash|
file_hash.each do |file_hash_key, file_hash_value|
if module_hash_key == file_hash_key
if found_modules_array.include?(module_hash_value)
duplicate_module_hash = {
module_hash_key => module_hash_value
}
duplicate_modules_array << duplicate_module_hash
end
found_modules_array << module_hash_value
end
end
end
end
end
在此代码中,files_array
是数组1,modules_array
是数组2。found_modules_array
是存储任何重复项的存储区,然后将它们推入duplicate_module_hash
,然后将其推入duplicates_modules_array
]
在这一点上,我的大脑开始爆炸,我决定寻求帮助,因为此解决方案:
我很乐意为您提供至少如何最好地通过逻辑思考的指导。也欢迎一些有关红宝石魔术的指南,这些指南可以帮助我达到最终结果。
首先,结构
arr1 = [
{0=>"pmet-add-install-module-timings.patch"},
{1=>"pmet-change-sample-data-load-order.patch"},
{2=>"pmet-configurable-recurring.patch"},
{3=>"pmet-consumers-run-staggered-by-sleep.patch"},
# etc
]
有点奇怪。使用平面哈希更容易使用,例如
h1 = {
0 => "pmet-add-install-module-timings.patch",
1 => "pmet-change-sample-data-load-order.patch",
2 => "pmet-configurable-recurring.patch",
3 =>"pmet-consumers-run-staggered-by-sleep.patch",
# etc
}
幸运的是,在两者之间进行转换非常容易:
h1 = arr1.reduce(&:merge)
h2 = arr2.reduce(&:merge)
从这一点来看,Enumerable methods(在这种情况下,经常使用的map,group_by和transform_values)将带您完成其余的步骤:
indexed_by_val = h2.
group_by { |k,v| v }.
transform_values { |vals| vals.map(&:first) }
这为您提供了val到索引的映射:
{
"magento2-base"=>[0, 8, 13],
"magento/module-sample-data"=>[1],
"magento/module-configurable-sample-data"=>[2],
# etc
}
然后我们可以用h1中的相应值替换那些索引列表:
result = indexed_by_val.transform_values do |indexes|
indexes.map do |idx|
{ idx => h1[idx] }
end
end
产生所需的数据结构:
{
"magento2-base"=>[
{0=>"pmet-add-install-module-timings.patch"},
{8=>"pmet-fix-module-loader-algorithm.patch"},
{13=>"pmet-stop-catching-sample-data-errrors-during-install.patch"}
],
"magento/module-sample-data"=>[
{1=>"pmet-change-sample-data-load-order.patch"}
],
"magento/module-configurable-sample-data"=>[
{2=>"pmet-configurable-recurring.patch"}
],
# etc
}
我确实注意到,在您指定的预期输出中,值是散列或数组。我建议反对这种做法。对于所有哈希的键和值,最好使用统一的数据类型。但是,如果您确实出于任何原因想要这样做,则并不难:
# I am not advising this approach
result2 = result.transform_values do |arr|
arr.length > 1 ? arr : arr[0]
end
顺便说一下,我知道这种功能性编程/可枚举的链接代码可能有点难以解读。因此,建议您逐行运行它,以便您理解。
-edit-
假设您使用的是我上面提到的统一数据结构,建议您对最终结果调用.transform_values { |vals| vals.reduce(&:merge) }
,以便这些值是单个哈希而不是多个哈希:
{
"magento2-base"=>{
0=>"pmet-add-install-module-timings.patch",
8=>"pmet-fix-module-loader-algorithm.patch",
13=>"pmet-stop-catching-sample-data-errrors-during-install.patch"
},
"magento/module-sample-data"=>{
1=>"pmet-change-sample-data-load-order.patch"
],
"magento/module-configurable-sample-data"=>{
2=>"pmet-configurable-recurring.patch"
},
# etc
}