有没有办法在 YAML 中别名/锚定数组?

发布于 2024-10-16 19:24:22 字数 724 浏览 3 评论 0原文

我正在使用 Jammit 为 Rails 应用程序打包资源,并且我有一些想要的资源文件包括在几个组中的每一个中。例如,我希望 Sammy 及其插件同时出现在我的 mobile中screen 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 无法理解的。是否有一种语法可以将一个数组的元素直接包含在另一个数组中?

NB:我意识到在这种情况下,SAMMY 数组中只有两个元素,因此为每个元素提供别名和引用也不会太糟糕。包裹。对于这种情况来说这很好,但是当有五个或十个具有特定加载顺序的元素时,很快就会变得难以维护。

I'm using Jammit to package assets up for a Rails application and I have a few asset files that I'd like to be included in each of a few groups. For example, I'd like Sammy and its plugins to be in both my mobile and screen JS packages.

I've tried this:

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

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

and this:

mobile:
  - *SAMMY

but both put the Sammy JS files in a nested Array, which Jammit can't understand. Is there a syntax for including the elements of an Array directly in another Array?

NB: I realize that in this case there are only two elements in the SAMMY Array, so it wouldn't be too bad to give each an alias and reference both in each package. That's fine for this case, but quickly gets unmaintainable when there are five or ten elements that have a specific load order.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

双马尾 2024-10-23 19:24:22

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

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

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

或者,正如已经建议的那样,展平代码片段中的嵌套列表。

注意:根据 yaml-online-parser,您的第一个建议不是 < 的有效使用;< (用于合并两个字典中的键。然后锚点必须指向我认为的另一个字典。

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

Alternatively, as already suggested, flatten the nested lists in a code snippet.

Note: according to yaml-online-parser, your first suggestion is not a valid use of << (used to merge keys from two dictionaries. The anchor then has to point to another dictionary I believe.

遮云壑 2024-10-23 19:24:22

如果您希望 mobile 等于 sammy,您可以这样做:

mobile: *SAMMY

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

If you want mobile to be equal to sammy, you can just do:

mobile: *SAMMY

However if you want mobile to contain other elements in addition to those in sammy, there's no way to do that in YAML to the best of my knowledge.

强者自强 2024-10-23 19:24:22

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

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

无法在 YAML 级别合并序列

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

mobile:
  - *SAMMY

您将获得嵌套序列 - 所以将它们展平!假设你有这样的嵌套序列的映射:(

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

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

Your example is valid YAML (a convenient place to check is YPaste), but it's not defined what the merge does. Per the spec, a merge key can have a value:

  1. A mapping, in which case it's merged into the parent mapping.
  2. A sequence of mappings, in which case each is merged, one-by-one, into the parent mapping.

There's no way of merging sequences on YAML level.

You can, however, do this in code. Using the YAML from your second idea:

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! }

(Of course, if you have a more complicated YAML file, and you don't want every sequence flattened (or they're not all sequences), you'll have to do some filtering.)

柠檬 2024-10-23 19:24:22

此解决方案仅适用于 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

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


其他编程语言

根据您的 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]))

This solution is for Symfony/PHP only (considerations for other languages, see below)

Note about array keys from the PHP array manual page:

Strings containing valid decimal ints, unless the number is preceded by a + sign, will be cast to the int type. E.g. the key "8" will actually be stored under 8. [...]

This means that if you actually index your anchor array with integer keys, you can simply add new keys by continuing the initial list. So your solution would look like this:

sammy: &SAMMY
  1: public/javascripts/vendor/sammy.js
  2: public/javascripts/vendor/sammy*.js

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

You can even overwrite keys and still add new ones:

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

In both cases the end result is a perfectly valid indexed array, just like before.


Other programming languages

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

For instance, in JS you can access numerical string keys by their integer value as well:

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

sammy["1"]; // "public/javascripts/vendor/sammy.js"
sammy[1]; // "public/javascripts/vendor/sammy.js"

But you'd need to keep in mind, that your initial array is now an object, and that you would need to iterate over it accordingly, e.g.:

Object.keys(sammy).forEach(key => console.log(sammy[key]))
她如夕阳 2024-10-23 19:24:22

这是一个仅使用 yaml 的有效示例,其中在列表中包含更复杂的项目(例如具有多个键的对象):

sammy:
  - &A1
    public/javascripts/vendor/sammy.js: asdf
    public/javascripts/vendor/sammyz.js: asdfz
  - &A2
    public/javascripts/vendor/sammy2.js: asdf2
    public/javascripts/vendor/sammy2z.js: asdf2z

mobile: [*A1, *A2, { 
  public/javascripts/something_else.js: else,
  public/javascripts/something_else2.js: else2,

}]

输出的 JSON 表示形式:

{
  "mobile": [
    {
      "public/javascripts/vendor/sammy.js": "asdf", 
      "public/javascripts/vendor/sammyz.js": "asdfz"
    }, 
    {
      "public/javascripts/vendor/sammy2.js": "asdf2", 
      "public/javascripts/vendor/sammy2z.js": "asdf2z"
    }, 
    {
      "public/javascripts/something_else.js": "else", 
      "public/javascripts/something_else2.js": "else2"
    }
  ], 
  "sammy": [
    ...
  ]
}

您可以得到简洁性,但需要权衡的是需要使用显式括号语法。

Here is a valid example using just yaml that includes more complicated items (like objects with multiple keys) in the list:

sammy:
  - &A1
    public/javascripts/vendor/sammy.js: asdf
    public/javascripts/vendor/sammyz.js: asdfz
  - &A2
    public/javascripts/vendor/sammy2.js: asdf2
    public/javascripts/vendor/sammy2z.js: asdf2z

mobile: [*A1, *A2, { 
  public/javascripts/something_else.js: else,
  public/javascripts/something_else2.js: else2,

}]

JSON representation of output:

{
  "mobile": [
    {
      "public/javascripts/vendor/sammy.js": "asdf", 
      "public/javascripts/vendor/sammyz.js": "asdfz"
    }, 
    {
      "public/javascripts/vendor/sammy2.js": "asdf2", 
      "public/javascripts/vendor/sammy2z.js": "asdf2z"
    }, 
    {
      "public/javascripts/something_else.js": "else", 
      "public/javascripts/something_else2.js": "else2"
    }
  ], 
  "sammy": [
    ...
  ]
}

You get brevity, but the trade-off is needing to use explicit bracket syntax.

国粹 2024-10-23 19:24:22

正如所建议的,当您需要展平列表时,至少在 ruby​​ 中,向 mobile 添加“!展平”类型说明符并实现一个扩展 Array 的类、添加 yaml_tag 并展平编码器 seq 是微不足道的init_with。

As it has been suggested, when you need to flatten a list, at least in ruby, it is trivial to add a "!flatten" type specifier to mobile and implement a class that extends Array, adds the yaml_tag and flattens the coder seq on init_with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文