Complicated A-Z problem I am attempting to create an 'a to z' listing on a site with 1000+ entries of people. The catch is that it needs to be indexed by surname unless that person doesn't have a surname, in which case it will use their forename.

I know what I need to end up with — an array of 'a' to 'z' as keys, with the value another array of people, indexed by their name with the entry id as the value. I can then iterate over this and create the relevant sections for styling.

Is this even possible in Twig? If so, how?
I base my example on the assumption that all people are Users (Element type User). If users are entries, you'd have to replace users by entries ;)

I don't think there's a way to do this without iterating through all users first, creating some sort of ordering attribute (if lastName != '' ? lastName : firstName). Then, you'd be able to group your array by your ordering attribute:

{# create a variable to hold all user data you need #}
{% set allUsers = [] %}

{# loop through users ... #}
{% for user in craft.users.find() %}
    {# 
        ... and set variable for each user, containing the info you need
        and an 'orderMeBy' attribute, set to the uppercased first character of lastName or firstName
    #}
    {% set thisUser = [{
        fullName : user.fullName,
        orderMeBy : user.lastName != '' ? user.lastName | slice(0,1) | upper : user.firstName | slice(0,1) | upper
    }] %}

    {# merge this user's info with your allUsers variable #}
    {% set allUsers = allUsers | merge (thisUser) %}
{% endfor %}

{# group 'allUsers' variable by 'orderMeBy' attribute #}
{% set groupedUsers = allUsers | group('orderMeBy') %}

{# create an array of all numbers and letters #}
{% set numbers = 0..9 %}
{% set letters = 'A'..'Z' %}
{% set allChars = numbers | merge(letters) %}

{# loop to chars and, if users in groupedUsers[char], display those users #}
{% for char in allChars %}
    {% if groupedUsers[char] is defined %}
    &lt;h2&gt;{{ char }}&lt;/h2&gt;
    &lt;ul&gt;
        {% for user in groupedUsers[char] %}
            &lt;li&gt;{{ user.fullName }}&lt;/li&gt;
        {% endfor %}
    &lt;/ul&gt;
    {% endif %}
{% endfor %}


If anyone knows a quicker and/or easier way, tell me :)