代码之家  ›  专栏  ›  技术社区  ›  Steve K

使用数组值作为散列键在Ruby中创建嵌套散列

  •  0
  • Steve K  · 技术社区  · 4 年前

    .patch

    以下是示例:

    文件目录(示例)

    |__ .gitkeep
    |__ pmet-add-install-module-timings.patch
    |__ pmet-change-sample-data-load-order.patch
    |__ pmet-stop-catching-sample-data-errrors-during-install.patch
    |__ pmet-fix-admin-label-word-breaking.patch
    |__ pmet-declare-shipping-factory-for-compilation.patch.disabled
    
    ...
    

    文件名: pmet-add-install-module-timings.patch

    diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php

    文件名: pmet-change-sample-data-load-order.patch

    diff --git a/vendor/magento/module-sample-data/etc/module.xml b/vendor/magento/module-sample-data/etc/module.xml

    文件名: pmet-stop-catching-sample-data-errrors-during-install.patch

    第一行: diff --git a/vendor/magento/framework/Setup/SampleData/Executor.php b/vendor/magento/framework/Setup/SampleData/Executor.php

    文件名: pmet-fix-admin-label-word-breaking.patch

    第一行: diff --git a/vendor/magento/theme-adminhtml-backend/web/css/styles-old.less b/vendor/magento/theme-adminhtml-backend/web/css/styles-old.less

    JSON文件示例

    {
        "patches": {
            "magento/magento2-base": {
                "Patch 1": "m2-hotfixes/pmet-add-install-module-timings.patch"
            },
            "magento/module-sample-data": {
                "Patch 2": "m2-hotfixes/pmet-change-sample-data-load-order.patch"
            },
            "magento/theme-adminhtml-backend": {
                "Patch 3": "m2-hotfixes/pmet-fix-admin-label-word-breaking.patch"
            },
            "magento/framework": {
                "Patch 4": "m2-hotfixes/pmet-stop-catching-sample-data-errrors-during-install.patch"
            }
        }
    }
    

    目前为止的解决方案 scrape.rb

    下面是完整的代码。我将进一步细分如下:

    files_hash = Hash.new
    modules = Array.new
    data_hash = {
        patches: {}
    }
    files = Dir["*.patch"]
    files.each do |file|
        files_hash.store(files.index(file), file)
    end
    files_hash.each do |key, file|
        value = File.open(file, &:readline).split('/')[3]
        if value.match(/module-/) || value.match(/theme-/)
            result = "magento/#{value}"
        else
            result = "magento2-base"
        end
        modules << result
        modules.each do |val|
            data_hash[:patches][val][key] = "m2-hotfixes/#{file}"
        end
    end
    print data_hash
    

    在强调问题之前,我需要首先详细说明我为实现预期的最终结果所做的工作:

    首先,我设置了一个空文件哈希、模块数组和数据哈希:

    files_hash = Hash.new
    modules = Array.new
    data_hash = {
        patches: {}
    }
    

    接下来,我扫描补丁文件目录 .补丁

    files = Dir["*.patch"]
    files.each do |file|
        files_hash.store(files.index(file), file)
    end
    

    magento/module-name , magento/theme-name 或者别的什么。两个 module-name theme-name magento/#{value} 语法。“其他东西”的情况下将使用 magento/magento2-base :

    files_hash.each do |key, file|
        value = File.open(file, &:readline).split('/')[3]
        if value.match(/module-/) || value.match(/theme-/)
            result = "magento/#{value}"
        else
            result = "magento2-base"
        end
        modules << result
    ...
    

    这不是我想要的 解决方案(如果差异结构发生变化怎么办?)但它现在可以工作了,而且我还不能很好地找到合适的正则表达式来搜索字符串并返回相同的结果。上面的代码给出了我想要的,它是以下数组:

    #=>["magento2-base", "magento/module-sample-data", "magento/theme-adminhtml-backend", "magento2-base"]
    

    接下来,虽然仍然能够从文件散列访问文件名和键,但我需要循环遍历这个数组并创建散列,其中数组值作为键,文件名作为值(附加到文件路径)。就像这样,(或者我是这么想的):

        modules.each do |val|
            data_hash[:patches][val][key] = "m2-hotfixes/#{file}"
        end
    end
    

    我对这部分代码有意见。运行此命令会出现以下错误:

    Traceback (most recent call last):
        4: from scrape.rb:10:in `<main>'
        3: from scrape.rb:10:in `each'
        2: from scrape.rb:18:in `block in <main>'
        1: from scrape.rb:18:in `each'
    scrape.rb:19:in `block (2 levels) in <main>': undefined method `[]=' for nil:NilClass (NoMethodError)
    

    我注意到如果我忽略 key data_hash data_hash[:patches][val] ,我得到一个散列值。

    那么,我明显的问题是:

    0 回复  |  直到 4 年前
        1
  •  0
  •   Steve K    4 年前

    下面是我想到的答案:

    require 'json'
    
    files_hash = Hash.new
    file_hash = Hash.new
    result_hash = Hash.new
    data_hash = Hash.new
    remap_hash = Hash.new 
    final_hash = {"patches" => {}}
    files = Dir["*.patch"]
    patches_file = File.dirname(File.expand_path(__FILE__)) + "/patches.json"
    
    files.each do |file|
        files_hash.store(files.index(file), file)
    end
    files_hash.each do |key, file|
        value = File.open(file, &:readline).split('/')[3]
        if value.match(/module-/) || value.match(/theme-/)
            result = "magento/#{value}"
        else
            result = "magento2-base"
        end
        data_hash[key] = result
        file_hash[key] = "m2-hotfixes/#{file}"
    end
    
    data_hash.each do |data_key, data_vals|
        file_hash.each do |file_key, file_vals|
            if data_key == file_key
                remap_hash[data_vals] = {
                    "Patch #{data_key}" => file_vals
                }
            end
        end
    end
    
    final_hash["patches"].merge!(remap_hash)
    
    File.open(patches_file, "w+") do |file|
        file.puts(final_hash.to_json)
    end
    

    patches.json 注意:

    {
        "patches": {
            "magento2-base": {
                "Patch 6": "m2-hotfixes/pmet-fix-module-loader-algorithm.patch"
            },
            "magento/module-downloadable-sample-data": {
                "Patch 2": "m2-hotfixes/pmet-fix-sample-data-code-generator.patch"
            },
            "magento/module-customer": {
                "Patch 3": "m2-hotfixes/pmet-visitor-segment.patch"
            }
        }
    }
    

    一些优点和缺点:

    赞成的意见

    它起作用了。令人惊叹的。

    1. 文件可能有需要应用于同一文件的重复修补程序。比如:

    {
        "patches": {
            "magento2-base": {
                "Patch 1": "m2-hotfixes/pmet-add-install-module-timings.patch"
                "Patch 6": "m2-hotfixes/pmet-fix-module-loader-algorithm.patch"
            },
            "magento/module-downloadable-sample-data": {
                "Patch 2": "m2-hotfixes/pmet-fix-sample-data-code-generator.patch"
            },
            "magento/module-customer": {
                "Patch 3": "m2-hotfixes/pmet-visitor-segment.patch"
            }
        }
    }
    

    我的解决方案需要考虑到这一点,因为Ruby不允许散列中出现重复键。

    我会欢迎一个更优雅的解决方案,以应对这一怪癖带来的挑战。