基于Ruby中一组通用键将两个数组缝合在一起的最佳方法是什么?

问题描述 投票:0回答:1

背景

我有两个散列数组,它们由一组共同的键关联:

数组1

[
    {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"}
]

数组2

[
    {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"}
]

注意,这些数组中的每个哈希具有相同的索引集,并且第二个数组在键0813以及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]

在这一点上,我的大脑开始爆炸,我决定寻求帮助,因为此解决方案:

  1. 不工作
  2. 不利用红宝石的力量
  3. 不是表演者

我很乐意为您提供至少如何最好地通过逻辑思考的指导。也欢迎一些有关红宝石魔术的指南,这些指南可以帮助我达到最终结果。

arrays ruby hash
1个回答
0
投票

首先,结构

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(在这种情况下,经常使用的mapgroup_bytransform_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
}
© www.soinside.com 2019 - 2024. All rights reserved.