Make array elements lowercase with Liquid filters for sorting

602 views Asked by At

I can't figure out how case-insesitively to sort an array containing strings: ["A", "C", "E", "b", "d"] into ["A", "b", "C", "d", "E"].

{% assign input = "A,C,E,b,d" | split:"," %}
{{ input | join: "-" }}
{{ input | map: 'downcase' | join: "-" }}
{{ input | map: 'downcase' | sort | join: "-" }}
{{ input | map: 'length' | join: "-" }}
{{ input | map: 'size' | join: "-" }}

What am I missing about map:?

Expected output:

A-C-E-b-d
a-c-e-b-d
a-b-c-d-e
1-1-1-1-1
1-1-1-1-1

Actual output:

A-C-E-b-d
----
----
----
----

Note: at first I tried map: downcase (without quotes), but got no implicit conversion from nil to integer.

2

There are 2 answers

1
Jonathan_W On BEST ANSWER

The sort_natural filter does a case-insensitive sort:

{% assign my_array = "zebra, octopus, giraffe, Sally Snake" | split: ", " %}

{{ my_array | sort_natural | join: ", " }}

Outputs giraffe, octopus, Sally Snake, zebra

1
TWiStErRob On

sort_natural was added after I asked the question. See other answer. I'll leave this answer here, because it shows how can you do a sorting by any key.

{% assign input = "A,C,E,b,d" | split:"," %}
{% capture intermediate %}{% for entry in input %}{{ entry | downcase }}{{ entry }}{% unless forloop.last %}{% endunless %}{% endfor %}{% endcapture %}
{% assign intermediate_sorted = intermediate | split:'' | sort %}
{% capture sorted %}{% for entry in intermediate_sorted %}{{ entry | split: '' | last }}{% unless forloop.last %}{% endunless %}{% endfor %}{% endcapture %}
{% assign sorted = sorted | split: '' %}
{{ sorted | join: "-" }}

will output A-b-C-d-E.

The US (Unit Separator, \u001F, not \u241F) and RS (Record Separator, \u001E, not \u241E) are the two characters unlikely to appear in the input, so they can be used safely most of the time. They could be , and | if you want to sort CSS IDs for example.