【问题标题】:Is there a way to alias/anchor an array in YAML?有没有办法在 YAML 中对数组进行别名/锚定?
【发布时间】:2011-06-24 08:26:06
【问题描述】:

我正在使用Jammit 为Rails 应用程序打包资产,并且我有一些资产文件希望包含在几个组中。例如,我希望 Sammy 及其插件在我的 mobilescreen JS 包中。

我试过了:

sammy: &SAMMY
  - public/javascripts/vendor/sammy.js
  - public/javascripts/vendor/sammy*.js

mobile:
  <<: *SAMMY
  - public/javascripts/something_else.js

还有这个:

mobile:
  - *SAMMY

但两者都将 Sammy JS 文件放在一个嵌套数组中,这是 Jammit 无法理解的。是否有将 Array 的元素直接包含在另一个 Array 中的语法?

NB:我意识到在这种情况下,SAMMY 数组中只有两个元素,因此在每个包中给每个元素一个别名和引用都不会太糟糕。在这种情况下这很好,但是当有五个或十个具有特定加载顺序的元素时,很快就会变得无法维护。

【问题讨论】:

标签: yaml assets


【解决方案1】:

我所知道的最接近的解决方案是这个:

sammy:
  - &SAMMY1
    public/javascripts/vendor/sammy.js
  - &SAMMY2
    public/javascripts/vendor/sammy*.js

mobile:
  - *SAMMY1
  - *SAMMY2
  - public/javascripts/something_else.js

或者,如前所述,在代码 sn-p 中展平嵌套列表。

注意:根据yaml-online-parser,您的第一个建议不是对

【讨论】:

  • 如果 sammy1/samm2 需要多个元素,这将不起作用
【解决方案2】:

如果你想让mobile 等于sammy,你可以这样做:

mobile: *SAMMY

但是,如果您希望 mobile 包含除 sammy 中的元素之外的其他元素,据我所知,在 YAML 中无法做到这一点。

【讨论】:

    【解决方案3】:

    您的示例是有效的 YAML(方便检查的地方是 YPaste),但没有定义合并的作用。根据spec,合并键可以有一个值:

    1. 一个映射,在这种情况下它被合并到父映射中。
    2. 一系列映射,在这种情况下,每个映射都被一个接一个地合并到父映射中。

    无法在 YAML 级别合并序列

    但是,您可以在代码中执行此操作。使用第二个想法中的 YAML:

    mobile:
      - *SAMMY
    

    您将获得嵌套序列 - 将它们展平!假设您有此类嵌套序列的映射:

    data = YAML::load(File.open('test.yaml'))
    data.each_pair { |key, value| value.flatten! }
    

    (当然,如果你有一个更复杂的 YAML 文件,并且你不希望每个序列都被展平(或者它们不是所有序列),你就必须进行一些过滤。)

    【讨论】:

    • 这是一个示例:yaml.org/ypaste/803/index.html。我刚刚再次检查并注意到这不是语法错误;就是这个构造不会创建一个平面数组;它创建了一个 Jammit 无法处理的地图。我刚刚编辑了问题以显示这一点。
    • @James,抱歉,我没有意识到您正在合并序列。已编辑。
    • 确保你 flatten(1) 用于浅展平,这样你就不会破坏值中的数组。
    【解决方案4】:

    此解决方案仅适用于 Symfony/PHP(其他语言的注意事项,见下文)

    注意PHP array manual page中的数组键:

    包含有效十进制整数的字符串,除非数字前面有 + 号,否则将被强制转换为 int 类型。例如。密钥“8”实际上将存储在 8 下。[...]

    这意味着,如果您实际上使用整数键索引您的锚数组,您可以通过继续初始列表来简单地添加新键。所以你的解决方案看起来像这样:

    sammy: &SAMMY
      1: public/javascripts/vendor/sammy.js
      2: public/javascripts/vendor/sammy*.js
    
    mobile:
      <<: *SAMMY
      3: public/javascripts/something_else.js
    

    您甚至可以覆盖键并添加新键:

    laptop:
      <<: *SAMMY
      1: public/javascripts/sammy_laptop.js
      3: public/javascripts/something_else.js
    

    在这两种情况下,最终结果都是一个完全有效的索引数组,就像以前一样。


    其他编程语言

    根据你的 YAML 实现你如何迭代你的数组,可以想象这也可以用于其他编程语言。虽然有一个警告。

    例如,在 JS 中,您也可以通过整数值访问数字字符串键:

    const sammy = {"1": "public/javascripts/vendor/sammy.js"}
    
    sammy["1"]; // "public/javascripts/vendor/sammy.js"
    sammy[1]; // "public/javascripts/vendor/sammy.js"
    
    

    但您需要记住,您的初始数组现在是一个对象,您需要相应地对其进行迭代,例如:

    Object.keys(sammy).forEach(key => console.log(sammy[key]))
    

    【讨论】:

      【解决方案5】:

      正如建议的那样,当您需要展平列表时,至少在 ruby​​ 中,向移动设备添加“!flatten”类型说明符并实现扩展 Array 的类,添加 yaml_tag 并展平init_with 上的 coder seq。

      【讨论】:

        猜你喜欢
        • 2021-03-07
        • 1970-01-01
        • 1970-01-01
        • 2020-02-26
        • 1970-01-01
        • 2019-03-04
        • 2015-11-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多