Sorting a custom array with strings and numbers in Liquid

Matija_
Shopify Partner
1 0 0

Hi,

I'm trying to sort an array of tags that contain strings and numbers in it.
Currently the array gets sorted like this:

How it's currently sorted:How I would like for it to be sorted:

module-hfov-105

module-hfov-108

module-hfov-127

module-hfov-68

module-hfov-69

module-hfov-72

module-hfov-75

module-hfov-90

module-hfov-68

module-hfov-69

module-hfov-72

module-hfov-75

module-hfov-90

module-hfov-105

module-hfov-108

module-hfov-127

 

Are there any solutions as to how I could achieve this? Would really appreciate any code examples.

Thanks in advance,

Matija

Replies 3 (3)

amorlett
Shopify Partner
186 12 30

look into {% capture %} in shopify cheat sheet, if you cant find the answer there is a shopify discord for developers

kallenconsult
Excursionist
32 0 8

I think if you could all the numerics having the same amount of digits, you'd be fine.  So, if you can add in a "0" in front of each of the number parts of the module names, you'd be golden:

 

module-hfov-68 becomes module-hfov-068

module-hfov-69 becomes module-hfov-069

module-hfov-72 becomes module-hfov-072

... etc.

 

Sorts are dumb.  They base it all on the characters as they encounter them.  This is why 127 is in front of 68.  The first thing the sort sees, after the dash, is a "1" which numerically, comes before "6".  Add a leading zero for those numbers less than 100 and the sort will work fine. 

 

Look through this code to give you some ideas:

{% assign products = "module-hfov-105,module-hfov-108,module-hfov-127,module-hfov-68,module-hfov-69,module-hfov-72,module-hfov-75,module-hfov-90" %}
{% assign productList = products | split: "," %}
{% for product in productList %}
  {% assign productNamePieces = product | split: "-" %}
  {% assign productNameSuffix = productNamePieces[2] | plus: 0 %}
    
  {% if productNameSuffix < 100 %}
    {% assign leadingZero = "0" %}
    {% assign newNumericIdentifier = leadingZero | append: productNamePieces[2] %}
    {% assign revisedProductName = productNamePieces[0] | append: "-" | append: productNamePieces[1] | append: "-" | append: newNumericIdentifier %}
  {% else %}
    {% assign revisedProductName = product %}
  {% endif %}
  {% if newProducts %}
    {% assign newProducts = newProducts|append: "," | append:revisedProductName %}
  {% else %} 
    {% assign newProducts = revisedProductName %}
  {% endif %}
{% endfor %}
{% assign newProductList = newProducts | split: "," %}

{% assign productList = productList | sort %}
{% assign newProductList = newProductList | sort %}

<h3>Old Product List</h3>
{% for product in productList %}
  {{ product }}<br />
{% endfor %}
<h3>Revised Product List</h3>
{% for product in newProductList %}
  {{ product }}<br />
{% endfor %}

 

Output:

Screenshot 2023-11-06 at 4.32.15 PM.png

kallenconsult
Excursionist
32 0 8

In the interest of passing on continued learning, I found a far more elegant way to do the zero-fill.  My lack of liquid experience was showing!  Thanks to @mattxwang for the suggestion back in 2019.

 

Instead of the 8 lines, we can wheedle it down to 2:

 

...
  {% assign productNameSuffix = productNamePieces[2] | plus: 0 %}
  {% if productNameSuffix < 100 %}
    {% assign leadingZero = "0" %}
    {% assign newNumericIdentifier = leadingZero | append: productNamePieces[2] %}
    {% assign revisedProductName = productNamePieces[0] | append: "-" | append: productNamePieces[1] | append: "-" | append: newNumericIdentifier %}
  {% else %}
    {% assign revisedProductName = product %}
  {% endif %}
...

 

to:

 

...
  {% assign newNumericIdentifier = productNamePieces[2] | prepend: '000' | slice: -3, 3 %}
  {% assign revisedProductName = productNamePieces[0] | append: "-" | append: productNamePieces[1] | append: "-" | append: newNumericIdentifier %}
 ...

 

Final code:

{% assign products = "module-hfov-105,module-hfov-108,module-hfov-127,module-hfov-68,module-hfov-69,module-hfov-72,module-hfov-75,module-hfov-90" %}
{% assign productList = products | split: "," %}
{% for product in productList %}
  {% assign productNamePieces = product | split: "-" %}
  {% assign newNumericIdentifier = productNamePieces[2] | prepend: '000' | slice: -3, 3 %}
  {% assign revisedProductName = productNamePieces[0] | append: "-" | append: productNamePieces[1] | append: "-" | append: newNumericIdentifier %}
  {% if newProducts %}
    {% assign newProducts = newProducts|append: "," | append:revisedProductName %}
  {% else %} 
    {% assign newProducts = revisedProductName %}
  {% endif %}
{% endfor %}
{% assign newProductList = newProducts | split: "," %}

{% assign productList = productList | sort %}
{% assign newProductList = newProductList | sort %}

<h3>Old Product List</h3>
{% for product in productList %}
  {{ product }}<br />
{% endfor %}
<h3>Revised Product List</h3>
{% for product in newProductList %}
  {{ product }}<br />
{% endfor %}