Answers.Body: <p><a href="https://craftcms.stackexchange.com/a/4914/57">Paul's answer</a> is good, but I suspect it would end up being a bit easier and cleaner if you just it from a <a href="http://buildwithcraft.com/docs/plugins/introduction" rel="nofollow noreferrer">plugin</a> so you could do all of your logic from PHP.</p>
  
  <p>The just return your sorted, assembled array back to the template to loop through.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-24T18:48:23.683Z
Answers.Text: I responded to the `Is this even possible in Twig? If so, how?` part of the question ;) Wanted to show that nearly everything is possible in Twig ... This is for the poor souls not able or willing to create plugins :)
Answers.UserDisplayName: Paul
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-24T18:49:47.257Z
Answers.Text: Of course. At some point the programmer in me starts to cringe seeing so much logic in a template is all. :)
Answers.UserDisplayName: Brad Bell
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-24T18:50:38.047Z
Answers.Text: Always ignore the programmer in you, it makes life so much easier ...
Answers.UserDisplayName: Paul
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-25T08:57:08.473Z
Answers.Text: I agree with Brad, I think I'll be writing my first plugin here.
Answers.UserDisplayName: hamishtaplin
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-24T18:45:13.883Z
Answers.LastActivityDate: 2014-11-24T18:45:13.883Z
Answers.LastEditDate: 2017-04-13T12:51:00.200Z
Answers.UserDisplayName: Brad Bell
Answers.Body: <p>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 ;)</p>
  
  <p>I don't think there's a way to do this without iterating through all users first, creating some sort of ordering attribute (<code>if lastName != '' ? lastName : firstName</code>). Then, you'd be able to group your array by your ordering attribute:</p>
  
  <pre><code>{# 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 %}
  </code></pre>
  
  <p>If anyone knows a quicker and/or easier way, tell me :)</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-24T18:42:21.723Z
Answers.LastActivityDate: 2014-11-24T18:42:21.723Z
Answers.UserDisplayName: Paul
Body: <p>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.</p>
  
  <p>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.</p>
  
  <p>Is this even possible in Twig? If so, how?</p>
  
Tags: <templating><entries><array>
Title: Complicated A-Z problem
ThreadText: # Complicated A-Z problem
  
  (Asked by: username_0 on 2014-11-24)
  
  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?
  
  **Tags:** templating, entries, array
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2014-11-24. Score: 5 | Accepted answer
  
  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 %}
      <h2>{{ char }}</h2>
      <ul>
          {% for user in groupedUsers[char] %}
              <li>{{ user.fullName }}</li>
          {% endfor %}
      </ul>
      {% endif %}
  {% endfor %}
  
  ```
  
  If anyone knows a quicker and/or easier way, tell me :)
  
  
  ---
  
  ### Answer by username_1 on 2014-11-24. Score: 1
  
  [username_2's answer](https://craftcms.stackexchange.com/a/4914/57) is good, but I suspect it would end up being a bit easier and cleaner if you just it from a [plugin](http://buildwithcraft.com/docs/plugins/introduction) so you could do all of your logic from PHP.
  
  The just return your sorted, assembled array back to the template to loop through.
  
  > **Comments:**
  > **username_2**: I responded to the `Is this even possible in Twig? If so, how?` part of the question ;) Wanted to show that nearly everything is possible in Twig ... This is for the poor souls not able or willing to create plugins :)  
  > **username_1**: Of course. At some point the programmer in me starts to cringe seeing so much logic in a template is all. :)  
  > **username_2**: Always ignore the programmer in you, it makes life so much easier ...  
  > **username_0**: I agree with username_1, I think I'll be writing my first plugin here.  
  
  ---
  
  