Simplest way of getting the maximum of two array lengths in Liquid/Jekyll?

In my Jekyll site, I have two arrays containing the contents of a collection.

{% assign A = site.mycollection | where: "type","A" %}
{% assign B = site.mycollection | where: "type","B" %}

What is the shortest way of getting the greater of the two lengths of these arrays? Currently, what I’m doing is:

{% assign max_len = A | size %}
{% assign len_B = B | size %}
{% if len_B > max_len %}
    {% assign max_len = len_b %}
{% endif %}

This seems like a lot of code for something so simple. I must be missing something, right?

Got it down to a one-liner, though this still seems overwrought:

{{ site.mycollection | group_by: "type" | map: "size" | sort | last }}
1 Like

Does your 2nd solution actually work? I am thinking that after your apply map you’ll reduce your two arrays to sizes and then you’ll get one of the two sizes as integers and not as array values.

Try this using .size based on https://stackoverflow.com/a/27321885/6250733

{% if A.size > B.size %}
    {% assign longest = A %}
{% else %}
    {% assign longest = B %}
{% endif %}

There is no ternary in Jekyll so you can’t do CONDITION ? A : B

See https://github.com/Shopify/liquid/issues/236#issuecomment-195512099

This could also be done with a plugin which uses ruby code. It will be more code to setup but it will mean if you use your filter repeatedly than you code will be cleaner.

[3, 2].max
=> 3

# compare length of two arrays
[[1,1,1], [1,1,1,1]].max
=> [1, 1, 1, 1]

Plugins need a lot of Ruby code but you could setup a reusable includes.

Try this - I haven’t tested this.

Note using includes.variable name allows use of a var passed to it.

_includes/max.html

{% if includes.first.size > includes.second.size %}
    {% assign longest = includes.first %}
{% else %}
    {% assign longest = includes.second %}
{% endif %}

Usage. Note the includes won’t render anything (unless you want it to) so I use it just to set a var

{% include max.html first=['a', 'b'] second=['a', 'b', 'c'] %}

Value of longest of the two arrays: {{ longest }}

I use includes for dealing with rendering HTML tags where i pass in a string value. I assume passing other data types like array would hopefully be supported too.

Does your 2nd solution actually work?

As far as I can tell, my second solution works just fine. Note from the post that the goal is to get the greater of the two lengths, not the largest array.

To test, I output each intermediate filter step to verify that I get what I want, but if you see something wrong I’d be happy to hear it.

{{ site.mycollection | group_by: "type" }}
--> an array of arrays

{{ site.mycollection | group_by: "type"  | map: "size" }}
--> an array of integers, the sizes of the groups

{{ site.mycollection | group_by: "type"  | map: "size"  | sort }}
--> a sorted array of integers

{{ site.mycollection | group_by: "type"  | map: "size"  | sort | last }}
--> the largest integer

I considered writing a plugin but figured I’d ask about a canonical way of doing it first. It really blows my mind that such a (supposedly) powerful system has such an anemic standard library.

Thank you for your replies. I appreciate the help!

Oh yes I had misunderstood, I see you want the integers.

Yes I have been frustrated as well when trying to work with arrays or even just get keys of a hash as below.

For interest a simple plugin

But I make do with what Jekyll can do which is still far easier than not using Jekyll.

Jekyll uses the Liquid syntax which is used in Python etc. for templating so the weakness could be a mix of the origins and not make Ruby syntax work
In Python you can use Jinja for liquid templating but it also supports native python code so you can use methods on strings for example that one normally uses in Python.