【问题标题】:Jekyll: sort collections by sizeJekyll:按大小对集合进行排序
【发布时间】:2018-04-18 13:04:21
【问题描述】:

我想按每个集合中的文档数对我的 Jekyll 集合进行排序。

site.collections 变量中的每个集合都有一个 docs 字段,docs 字段(这是一个文档数组)有一个 size 字段,这是该集合中的文档数(参见documentation)。

但是,这样的事情不起作用:

{% assign sorted = site.collections | sort: 'docs.size' %}

{% for coll in sorted %}
  ...
{% endfor %}

结果是

Liquid Exception: no implicit conversion of String into Integer

看来sort的参数只能是被排序对象类型的直接字段,而不是其字段的字段。

有没有办法按集合包含的文档数量对集合进行排序?

【问题讨论】:

  • 您是否尝试过使用{% assign sorted = site.collections | sort: docs.size %}?即 sort: docs.size
  • 你的意思是没有引号?是的,那么错误是Liquid Exception: Liquid error (line 14): comparison of Jekyll::Drops::CollectionDrop with Jekyll::Drops::CollectionDrop failed。
  • 我不确定是否存在错误或者它不应该像这样工作。排序过滤器上的documentation 不是很有帮助。
  • Jekyll 使用自定义的sort 过滤器。再试一次{% assign sorted = site.collections | sort: 'size' %}
  • 然后它会编译,但排序顺序不是按文档数,而是与我传递一个不存在的字段进行排序时相同,例如sort: 'foo'.

标签: jekyll liquid


【解决方案1】:
  1. 构建可用大小的数组:

    {% assign sorted = '' | split: "" %}
    {% for coll in site.collections %} 
        {% assign sorted = sorted| append: coll.docs.size %} 
    {% endfor %}
    
  2. 对上面的数组进行排序。

  3. 迭代上述数组,所有集合仅打印大小与排序后的数组编号匹配的集合。

【讨论】:

  • 我知道你的意思。但问题是,像这样创建的数组将是一个字符串数组,对这个数组进行排序不会产生正确的数字顺序。是否可以使用 Liquid 创建整数数组?
【解决方案2】:

好的,我以一种相当丑陋的方式实现了它,类似于marcanuy's answer。

<!-- Create a comma-separated string of all the sizes of the collections -->
{% for coll in site.collections %}
    {% if coll.title %}
      {% if coll.docs.size < 10 %}
        {% assign str = coll.docs.size | prepend: "00" %}
      {% elsif coll.docs.size < 100 %}
        {% assign str = coll.docs.size | prepend: "0" %}
      {% else %}
        {% assign str = coll.docs.size %}
      {% endif %}
      {% assign sizes = sizes | append: str | append: "," %}
    {% endif %}
{% endfor %}

<!-- Remove last comma of string -->
{% assign length = sizes | size | minus: 1 %}
{% assign sizes = sizes | slice: 0, length %}

<!-- Split string into array, sort DESC, and remove duplicate elements -->
{% assign sizes = sizes | split: "," | sort | reverse | uniq %}

<!-- Iterate through sizes, and for each size print those collections that have this size -->
{% for s in sizes %}
  {% for coll in site.collections %}
    {% assign i = s | plus: 0 %}
    {% if coll.docs.size == i %}
      <p>{{ coll.title }}: {{ i }} documents</p>
    {% endif %}
  {% endfor %}
{% endfor %}

主要的困难是像这样创建的大小数组是一个字符串数组,对其进行排序会导致按字母排序,而不是按数字排序(例如"15" 在"2" 之前)。

为了解决这个问题,我将 "00" 添加到小于 10 的数字前,将 "0" 添加到小于 100 的数字前。这使得字母排序顺序与所需的数字排序顺序一致。

然后我遍历这些大小(仍然是字符串),并即时将它们转换为整数(通过plus: 0),以便我可以将它们与每个集合的docs.size 字段进行比较。

这很冗长,但由于它仅在生成站点时执行,而不是在生产模式下的每个请求时执行,所以没关系。

不过,我们欢迎更好的解决方案!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2021-01-15
    相关资源
    最近更新 更多