liquid
liquid copied to clipboard
Numeric sort
I am attempting to design a Shopify order template and need the orders to print in order (numerically) by product number. Unfortunately it ends up in this order: 01 07 104 13
I have also tried the "sort_natural" filter. Any suggestions? Is there a better filter/pipe? I can alter the product codes so there are no leading zeros, but that will not fix the three digit problem...
Thanks for any assistance.
First, if you prepend codes such that the length is always the same, string sorting will work. This means, use 001
instead of 01
.
If you can't do that, I think the issue there is that the inputs are strings, and so the comparison uses string comparison.
irb(main):004:0> Liquid::Template.parse("{{ a | sort }}").render("a" => [10, 2, 3])
=> "2310"
irb(main):005:0> Liquid::Template.parse("{{ a | sort }}").render("a" => ['10', '2', '3'])
=> "1023"
There are some unreasonably complex ways of achieving this transformation:
Liquid::Template.parse("{% for i in a %}{% assign wrapped = i | floor | compact %}{% assign b = b | concat: wrapped %}{% endfor %}{{ b | sort }}").render("a" => ['10','2','3'])
=> "2310"
but we could consider adding a sort_numeric
filter, which sounds much more reasonable.
coming in late on this, but I have a similar issue with needing to sort by version numbers. say I have a list of version numbers like 1.1.1
, 1.1.2
, ... 1.1.10
currently the resulting order is 1.1.1
, 1.1.10
, 1.1.2
...
it would be great if a potential sort_numeric
type filter could take these scenarios into account as well. failing that, is there any data munging that could help out in getting this right in the current implementation?
Hello chums,
This is a real pain for us because it looks horrible! A sort_numeric
filter would be really handy!
This is worse than described here. I thought the values would always be treated as strings at least, but they're not.
Values are always read as numbers and then converted to strings before sorting. Thus values with a leading "0" are read as octal numbers and invalid octal values won't be sorted correctly. So using 001
, 002
,... will break when it gets to 008
and 009
and the like.
If I want all values to be treated as strings I have to use quotes or a prefix different than "0" in every value.
Examples that work:
-
"001"
,"002"
,... -
101
,102
,... -
A001
,A002
,...
This is really anoying while still not fixed and it doesn't work like written in docs. https://shopify.dev/api/liquid/filters/sort#sort-sort-by-an-array-item-property in shopify liquid with metaobjects if i sort for a numeric integer field i get null. ` {% assign topic_faqs = shop.metaobjects.faq.values | sort: 'question' %} {{ topic_faqs | json }} => Output values
importance field = integer in Shopify metaobject value definition
{% assign topic_faqs = shop.metaobjects.faq.values | sort: 'importance' %}
{{ topic_faqs | json }} => Output is null
`
So not only the sorting isn't working right with numeric values, it returns null.
This is really important liquid functionality thats not working like expected and the docs say. After nearly 5 years of open issue, and a start to add numeric #1028 sort it's pretty shamefull for a big company like shopify, to not fix this and deliver a reliable numeric sort filter for liquid.
Regards Spencer
Still need it to sort metaobjects properly
Chiming in here, it's pretty weird that sorting can't sort based on a numeric data type - that's 101 level functionality
2: difficult 0: sorting 1: is
Even Yoda can't get it right
But seriously please we need this! I have to use javascript to sort right now. Seems crazy
Thank you @spencer-j for confirming that metaobjects are completely broken. I was so confused.