Liquid: Могу ли я получить случайный элемент из массива?

Я пытаюсь выбрать случайный элемент из массива — возможно ли это с помощью Liquid/Jekyll?

Я могу создать массив - и получить доступ к заданному индексу... но есть ли способ "перетасовать" массив, а затем выбрать индекс и, таким образом, получить случайный элемент из массива?

prefix: ["Foo", "Bar", "Baz"]
---

{{ page.prefix[1] }}

# outputs "Bar"

person rsturim    schedule 08.02.2012    source источник
comment
Теперь на этот вопрос есть ответ здесь: stackoverflow.com/a/28323813/2838033 — добавление этого на случай, если кто-то придет из Google .   -  person mechalynx    schedule 11.08.2017


Ответы (6)


В Liquid нет фильтра для выбора случайного элемента из массива или целочисленного интервала.

Если вы хотите, чтобы Jekyll делал это, вам нужно создать расширение, чтобы добавить этот жидкий фильтр.

Однако я должен отметить, что при этом будет выбираться случайный элемент каждый раз, когда страница создается, но не каждый раз, когда страница просматривается.

Если вы хотите получать разные случайные значения при каждом посещении страницы, лучше всего использовать javascript и позволить клиенту выбрать случайное значение. Однако вы можете использовать жидкость для создания соответствующего javascript.

person kikito    schedule 08.02.2012
comment
Liquid теперь поддерживает это. shopify.github.io/liquid/basics/types/#array - person williamli; 06.06.2019
comment
@williamli вопрос был о выборе случайных элементов из массивов. Ваша ссылка, кажется, не обеспечивает эту функцию. - person kikito; 10.06.2019


Вы можете создать плагин для получения случайного элемента. Что-то вроде этого:

module Jekyll
  module RandomFilter
    # Use sample to get a random value from an array
    #
    # input - The Array to sample.
    #
    # Examples
    #
    #   random([1, 2, 3, 4, 5])
    #   # => ([2])
    #
    # Returns a randomly-selected item out of an array.
    def random(input)
      input.sample(1)
    end
  end
end

Liquid::Template.register_filter(Jekyll::RandomFilter)

Затем сделайте что-то подобное в своем шаблоне для реализации:

{% assign myArray = '1|2|3|4|5 | split: '|' %}
{% assign myNumber = myArray | random %}
person Brendan    schedule 17.11.2015
comment
Как я могу сделать это в Shopify? - person ADTC; 04.02.2018
comment
@ADTC Не знаю! - person Brendan; 05.02.2018
comment
Я думаю, что это ответ пользователя 2517028 - person ADTC; 06.02.2018

Возможно, вы сможете сделать это только в Liquid, но это может быть менее универсальное решение, подобное тому, которое предоставил @Brendan. Согласно этой статье , вы можете сгенерировать случайное число жидкости между min и max. Так просто:

  • Назначьте минимальное значение 0 и максимальное значение длины вашего массива.
  • Перебирайте массив, пока не найдете случайное число и не выберите элемент.

Вот пример, получите индекс случайного массива:

{% assign min = 0 %}
{% assign max = prefix.size %}
{% assign diff = max | minus: min %}
{% assign randomNumber = "now" | date: "%N" | modulo: diff | plus: min %}

Затем найдите случайное значение:

{{ prefix[randomNumber] }}
person user2517028    schedule 17.10.2017

Без использования плагина (что может быть требованием, например, если вы используете страницы github) и не хотите, чтобы выбор устанавливался только во время сборки/перестроения.

Это использует коллекции в качестве источника данных и некоторые флаги функций, установленные на главной странице.

{% if page.announcements %}
    <script>
        // homepage callout
        var taglines=[ 
         {% for txt in site.announcements %} 
           {{ txt.content | markdownify | jsonify | append: "," }}
        {% endfor %}
        ]
        var selection = document.querySelector('#tagline') !== null;
        if(selection) {
            document.querySelector('#tagline').innerHTML = taglines[ Math.floor(Math.random()*taglines.length) ];
        }
     </script>
{% endif %}

Я использую markdownify для обработки контента, jsonify, чтобы сделать его безопасным для JavaScript, а затем добавляю запятую, чтобы создать свой массив.

Затем Javascript заполняет его случайным образом при загрузке страницы.

Добавить коллекцию в config.yml

collections:
   announcements:

Добавить отметку на страницу

---
layout: home
title: 
slider: true
announcements: true    
---

элемент содержимого коллекции (test.md)

---    
published: true
---

This is a test post
person Mat    schedule 03.01.2020

Вы можете адаптировать Liquid::Drop и внести в белый список метод Ruby sample.

См. https://github.com/Shopify/liquid/blob/master/lib/liquid/drop.rb#L69:

Вам нужно будет изменить:

blacklist -= [:sort, :count, :first, :min, :max, :include?]

to:

blacklist -= [:sort, :count, :first, :min, :max, :include?, :sample]

Далее вы можете просто использовать:

{{ some_liquid_array.sample }}   
person joost    schedule 25.08.2014