Split a data file’s objects into array, and display matching values

Hi there, I’ve got a data file in which each entry has an object whose value is a comma-separated series of values. I’m trying to split those values into arrays, and loop through them, and group together objects with common values.

Here is my data file (people.yml):

- person: Jane
  scores: 3, 5, 9

- person: John
  scores: 7, 11, 15

- person: Jessie
  scores: 5, 9, 19

- person: Jay
  scores: 3, 13, 17

Here is my loop so far:

{% assign score_arrays = site.data.people.scores | split: ", " %}

## People with a score of 5

<ul>
  {% for item in site.data.people %}
    {% if score_arrays == 5 %}
      <li>
        {{ item.person }}
      </li>
    {% endif %}
  {% endfor %}
</ul>

Expected output:

<h2>People with a score of 5</h2>

<ul>
  <li>
    Jane
  </li>
  <li>
    Jessie
  </li>
</ul>

Thank you for any help you can provide.

You can get the length of an array in Liquid with the size attribute or filter. For example: if score_arrays.size == 5

Note that you could directly store the scores as arrays by adding square brackets. Example:

- person: Jane
  scores: [3, 5, 9]
1 Like

Thanks for the tip about using brackets for arrays. I didn’t know that.

But the size filter, unless I’m misunderstanding, is for counting the size of an array. Whereas I’m trying to match individual numbers within an array. For example, if 2 people in the data file have scores that include a 5, then I want to display a list of those 2 people.

First, remove the blank lines from your yaml data file and update it with the square brackets from @chuckhoupt 's reply

Then, edit the liquid template to be :

<ul>
  {% for item in site.data.people %}
    {% for score in item.scores %} 
      {% if score == 5 %}
        <li>
          {{ item.person }}
        </li>
        {% break %} 
      {% endif %} 
    {% endfor %}
  {% endfor %}
</ul>

There are two loops :

  • The outer one loops over people from your data files
  • The inner one loops over each person’s scores

Inside the inner loop there’s a condition that displays the person as soon as it finds a score of 5, and then uses {% break %} to stop the loop (to prevent a person from being displayed multiple times in case its scores array contains more than one 5)

Doh! Completely misread the question. Thanks to @pcouy for the answer.

Another option might be to use Jekyll’s where_exp filter and contains operator to create sub-set arrays by score (untested code):

{{assign score5 = site.data.people | where_exp: "person", "person.scores contains 5" }}
2 Likes

Thank you, both, for your help. The answer is simpler than I would have expected. I didn’t know about that trick of turning values into an array using brackets. Much appreciated, both of you.

1 Like

@andrewlobo don’t forget to mark the thread as solved

1 Like