Using variants on the collection page instead of products

I have a product with 3 colours and 4 sizes. Not all colours have all 4 sizes. I want to output the 3 colours variants on the collection page instead of just the one product, and underneath I want to show the sizes that are available for that colour.

My code works ok, and just outputs one variant from each colour. However I’m stuggling to write the code that will match up which colours have which sizes. At the moment this just outputs all the available sizes for the product not the available sizes for the variant.

This is my code.

{% for product in collection.products %}
{% assign options = product.options %}
{% assign have_color = false %}
{% assign size_index = false %}
{% for option in options %}
{% comment %}Check if there is a color option{% endcomment %}
{% if option == “Color” or option == “Colour” %}
{% assign have_color = forloop.index0 %}

{% endif %}
{% comment %}Get the size index{% endcomment %}
{% if option == “Size” %}
{% assign size_index = forloop.index0 %}
{% endif %}
{% endfor %}

{% for variant in product.variants %}

{% for option in options %}
{% comment %}Check if there is a color option{% endcomment %}
{% if option == “Color” or option == “Colour” %}
{% assign have_color = forloop.index0 %}
{% endif %}
{% comment %}Get the size index{% endcomment %}
{% if option == “Size” %}
{% assign size_index = forloop.index0 %}
{% endif %}
{% endfor %}
{% endfor %}

{% if have_color != false %}
{% assign variants = product.variants %}
{% assign colorlist = ‘’ %}
{% assign sizelist = ‘’ %}
{% assign color = ‘’ %}

{% comment %}Get All Sizes{% endcomment %}
{% for variant in variants %}
{% comment %}We use the [email removed] to wrap the string since sizes tend to have parts of other sizes, example S,XS,L,XL,XXL{% endcomment %}
{% assign string_check = variant.options[size_index] | append: [email removed] | prepend: [email removed] %}
{% unless sizelist contains string_check %}
{% capture sizelist %}{% unless forloop.first %}{{sizelist}},{% endunless [email removed] variant.options[size_index] [email removed] endcapture %}
{% endunless %}
{% endfor %}

{% assign sizelist_array = sizelist | replace: [email removed] ‘’ | split: ‘,’ %}
{% for variant in variants %}
{% capture color %}
{{ variant.options[have_color] }}
{% endcapture %}
{% unless colorlist contains color %}
{% assign product = variant %}

{%- assign image_src=variant.image.src -%}
{{ image_src.alt | escape }}
{{ product.title }} and {{ color | uppercase}} and the price is {{ product.price | money_with_currency }} - link
{{ color | downcase }}

Available sizes

    {% for size in sizelist_array %} {% if variant.available %}
  • {{ size }} | {{ color }}
  • {% endif %} {% endfor %}
{% capture tempList %} {{colorlist | append: color | append: ' '}} {% endcapture %} {% assign colorlist = tempList %} {% endunless %} {% endfor %} {% endif %} {% endfor %}