有没有办法在 YAML 使用别名或锚定一个数组?

我正在使用 该死为一个 Rails 应用程序打包资产,我有一些资产文件,我希望包含在每个组中。例如,我希望 山姆和它的插件都在我的 mobilescreen JS 包中。

我试过了:

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


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

and this:

mobile:
- *SAMMY

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

注意: 我意识到在这种情况下,SAMMY数组中只有两个元素,所以在每个包中给每个元素一个别名和一个引用也不是太糟糕。对于这种情况来说,这很好,但是当有五个或十个元素具有特定的加载顺序时,很快就无法维护了。

53754 次浏览

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

mobile: *SAMMY

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

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

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

在 YAML 级别无法合并序列

然而,你可以用代码来做这件事,使用你第二个想法的 YAML:

mobile:
- *SAMMY

you'll get nested sequences - so flatten them! Assuming you have a mapping of such nested sequences:

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

(当然,如果您有一个更复杂的 YAML 文件,并且您不希望每个序列都变平(或者它们不是所有的序列) ,那么必须进行一些筛选。)

Closest solution I know of is this one:

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


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

或者,如前所述,将代码段中的嵌套列表展开。

注意: 根据 Yaml 在线解析器,您的第一个建议不是 < < (用于合并来自两个字典的键。然后锚必须指向另一本字典,我相信。

正如有人建议的那样,当您需要展开列表时,至少在 Ruby 中,添加一个“ !类型说明符,并实现一个类,该类扩展 Array,添加 yaml _ tag,并在 init _ with 上平坦化编码器 seq。

此解决方案仅适用于 Symfony/PHP (其他语言的考虑,见下文)

关于 PHP 数组手册页中的数组键,请注意:

包含有效十进制整数的字符串(除非数字前面有 + 符号)将转换为 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

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


其他编程语言

Depending on your YAML implementation 还有 how you iterate over your array, this could conceivably also be used in other programming languages. Though with a caveat.

例如,在 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]))