Answers.Body: <p>There’s a lot to unpack here. Before I get to the solution, I’ll step through each of your examples, line-by-line. Hopefully that will help explain the behavior you’re seeing.</p>
  
  <h2>First Example</h2>
  
  <pre><code>{# Get all entries from the section. #}
  {% set entries = craft.entries.section('mySection') %}
  </code></pre>
  
  <p>Your comment is correct – this will fetch all the entries from section <code>mySection</code> and assign them to a new variable called <code>entries</code>.</p>
  
  <pre><code>{# Loop through the entries and get the user account associated with each. #}
  {% for profiles in entries %}
  </code></pre>
  
  <p>Start a loop on the <code>entries</code> variable. Within the loop, each profile entry will be represented by a <code>profiles</code> variable.</p>
  
  <p><em>Note: it’s misleading to call your variable “profiles” rather than “profile”, since it will only represent a single profile entry.</em></p>
  
  <pre><code>    {% set users = profiles.userAccount %}
  </code></pre>
  
  <p>Fetch all of the user accounts related to the current profile (<code>profiles</code>) via the <code>userAccount</code> field, and assign them to a new variable called <code>users</code>.</p>
  
  <pre><code>    {% if users|length %}
  </code></pre>
  
  <p>Only do the following if there were any related users…</p>
  
  <pre><code>        {% for year, user in users|group('myYearField') %}
  </code></pre>
  
  <p>Turn the users (<code>users</code>) that are related to the current profile (<code>profiles</code>) into a multi-dimensional array, grouped by their <code>myYearField</code> field values. Then start a loop on that multi-dimensional array. Within the loop, each <code>myYearField</code> value will be represented by a <code>year</code> variable, and the array of grouped user accounts will be represented by a <code>user</code> variable.</p>
  
  <p><em>Note: This is where things start really going wrong. You want to group <strong>all</strong> of your users by year – not just the ones that are related to the current profile. Also, your choice of “user” as a variable name here is misleading since it’s actually an array of grouped users; not a single user.</em></p>
  
  <pre><code>            &lt;h4&gt;{{ year }}&lt;/h4&gt; {# 2016 #}
  </code></pre>
  
  <p>Output the current grouping’s <code>myYearField</code> value, which was assigned to a <code>year</code> variable.</p>
  
  <pre><code>            &lt;ul class="list-unstyled"&gt;
                  {% for user in users %}
  </code></pre>
  
  <p>Start a loop on the same <code>users</code> variable that you’re already in the middle of looping through. <code>users</code> here refers to the same <code>users</code> variable that was defined in the 3rd codeblock.</p>
  
  <pre><code>                    &lt;li&gt;&lt;a href="{{ profiles.url }}"&gt;{{ user.name }}&lt;/a&gt;&lt;/li&gt;
  </code></pre>
  
  <p>Output the profile entry’s (<code>profiles</code>) URL, and the current user’s (<code>user</code>) name.</p>
  
  <pre><code>                {% endfor %}
  </code></pre>
  
  <p>Close out the loop on the user accounts related to the current profile entry (<code>users</code>).</p>
  
  <pre><code>            &lt;/ul&gt;
          {% endfor %}
  </code></pre>
  
  <p>Close out the loop on the multi-dimensional array of year-user groupings based on the user accounts related to the current profile entry (<code>users</code>).</p>
  
  <pre><code>    {% endif %}
  </code></pre>
  
  <p>Close out the conditional checking if there any users related to the current profile entry.</p>
  
  <pre><code>{% endfor %}
  </code></pre>
  
  <p>Close out the loop on the profile entries (<code>entries</code>).</p>
  
  <hr>
  
  <h2>Second Example</h2>
  
  <pre><code>{% set allProfiles = craft.entries.section('mySection') %}
  </code></pre>
  
  <p>Fetch all the entries from section <code>mySection</code> and assign them to a new variable called <code>allProfiles</code>.</p>
  
  <pre><code>{% if allProfiles|length %}
  </code></pre>
  
  <p>Only do the following if there were any profile entries…</p>
  
  <pre><code>    {{ allProfiles|length }} {# 3 #}
  </code></pre>
  
  <p>Output the total number of profile entries.</p>
  
  <pre><code>    {% for profiles in allProfiles %}
  </code></pre>
  
  <p>Start a loop on the <code>allProfiles</code> variable. Within the loop, each profile entry will be represented by a <code>profiles</code> variable.</p>
  
  <p><em>Note: as with the last example, it’s misleading to call your variable “profiles” rather than “profile”, since it will only represent a single profile entry.</em></p>
  
  <pre><code>        {% for profile in profiles.userAccount %}
  </code></pre>
  
  <p>Fetch all of the user accounts related to the current profile (<code>profiles</code>) via the <code>userAccount</code> field. Start a loop on the user accounts. Within the loop, each user account will be represented by a <code>profile</code> variable.</p>
  
  <p><em>Note: it’s misleading to call your variable “profile”, since it is actually the user account, not the profile entry.</em></p>
  
  <pre><code>            {% for year, user in profile|group('yearFieldHandle') %}
  </code></pre>
  
  <p>Turn the current user account (<code>profile</code>) into a multi-dimensional array, grouped by its properties’ <code>yearFieldHandle</code> sub-property values (which isn’t a thing). Then start a loop on that multi-dimensional array. Within the loop, each <code>yearFieldHandle</code> value will be represented by a <code>year</code> variable, and the array of grouped user account properties will be represented by a <code>user</code> variable.</p>
  
  <p><em>Note: Since <code>profile</code> is a single element (the user account) and not an array of elements, nothing about this is likely doing what you expected it to.</em></p>
  
  <pre><code>                &lt;h1&gt;{{ year }}&lt;/h1&gt;  {# No output #}
  </code></pre>
  
  <p>Output the current grouping’s <code>yearFieldHandle</code> value, which was assigned to a <code>year</code> variable. (This is the equivalent of doing something like <code>profile.id.yearFieldHandle</code>. It’s expected that you wouldn’t get any output.)</p>
  
  <pre><code>                &lt;h2&gt;{{ profile.firstName }}&lt;/h2&gt;    {# Bob #}
  </code></pre>
  
  <p>Output the user account’s first name.</p>
  
  <pre><code>                &lt;h3&gt;{{ profile.myYear }}&lt;/h3&gt; {# 2016 #}
  </code></pre>
  
  <p>Output the user account’s <code>myYear</code> custom field value.</p>
  
  <pre><code>            {% endfor %}
  </code></pre>
  
  <p>Close out the loop on the multi-dimensional array of year-user account property groupings based on the current user account defined by the parent loop.</p>
  
  <pre><code>        {% endfor %}
  </code></pre>
  
  <p>Close out the loop on the user accounts related to the current profile entry.</p>
  
  <pre><code>    {% endfor %}
  </code></pre>
  
  <p>Close out the loop on the profile entries (<code>allProfiles</code>).</p>
  
  <pre><code>{% endif %}
  </code></pre>
  
  <p>Close out the conditional checking if there any profile entries.</p>
  
  <hr>
  
  <h2>Solution</h2>
  
  <p>To group all of your profiles by their related user accounts’ custom date fields, first let’s load the profiles, <a href="https://craftcms.com/docs/templating/eager-loading-elements" rel="noreferrer">eager-loaded</a> with their related user accounts:</p>
  
  <pre><code>{% set profiles = craft.entries({
      section: 'userProfiles',
      with: ['userAccount']
  }) %}
  </code></pre>
  
  <p>Next let’s group the profiles by the <code>myYear</code> custom field on their related user accounts:</p>
  
  <pre><code>{% set profilesByYear = profiles|group('userAccount[0].myYear') %}
  </code></pre>
  
  <p>Now we can loop through the years, and their corresponding user profiles/accounts:</p>
  
  <pre><code>{% for year, yearProfiles in profilesByYear %}
      &lt;h1&gt;{{ year }}&lt;/h1&gt;
  
      {% for profile in yearProfiles %}
          {% set user = profile.userAccount[0] ?? null %}
          {% if user %}
              &lt;h2&gt;{{ user.firstName }}&lt;/h2&gt;
              &lt;h3&gt;{{ user.myYear }}&lt;/h3&gt;
          {% endif %}
      {% endfor %}
  {% endfor %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-19T15:02:28.080Z
Answers.Text: This is a fantastic response. Thank you for taking the time to write this all out!
Answers.UserDisplayName: Damon
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-18T17:44:09.427Z
Answers.LastActivityDate: 2016-10-18T17:44:09.427Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>I have been able to successfully <a href="https://craftcms.stackexchange.com/questions/16748/how-can-i-group-entries-based-on-a-datetime-field">group entries via dateTime field</a>. I have been trying to carry over the same type of logic only instead of using <code>.date</code> just key off of the field value.</p>
  
  <pre><code>{# Get all entries from the section. #}
  {% set entries = craft.entries.section('mySection') %}
  
  {# Loop through the entries and get the user account associated with each. #}
  {% for profiles in entries %}
      {% set users = profiles.userAccount %}
  
      {% if users|length %}
          {% for year, user in users|group('myYearField') %}
              &lt;h4&gt;{{ year }}&lt;/h4&gt; {# 2016 #}
              &lt;ul class="list-unstyled"&gt;
                  {% for user in users %}
                      &lt;li&gt;&lt;a href="{{ profiles.url }}"&gt;{{ user.name }}&lt;/a&gt;&lt;/li&gt;
                  {% endfor %}
              &lt;/ul&gt;
          {% endfor %}
      {% endif %}
  {% endfor %}
  </code></pre>
  
  <p>Currently what I am getting is:</p>
  
  <pre><code>2016
      User
  2016
      User
  ...
  </code></pre>
  
  <p>What I am trying to get (I swear I had this working at one point) is this:</p>
  
  <pre><code>2016
      User
      User
  
  2017
     User
     User
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>It seems my trouble comes from not accessing the <code>users</code> field correctly.
  Updated (but still incorrect) example:</p>
  
  <pre><code>{% set allProfiles = craft.entries.section('mySection') %}
  {% if allProfiles|length %}
      {{ allProfiles|length }} {# 3 #}
      {% for profiles in allProfiles %}
          {% for profile in profiles.userAccount %}
              {% for year, user in profile|group('yearFieldHandle') %}
                  &lt;h1&gt;{{ year }}&lt;/h1&gt;  {# No output #}
                  &lt;h2&gt;{{ profile.firstName }}&lt;/h2&gt;    {# Bob #}
                  &lt;h3&gt;{{ profile.myYear }}&lt;/h3&gt; {# 2016 #}
              {% endfor %}
          {% endfor %}
      {% endfor %}
  {% endif %}
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T19:25:19.507Z
Comments.Text: To be clear, is `myYearField` a DateTime or PlainText field?
Comments.UserDisplayName: Mats Mikkel Rummelhoff
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T20:32:19.807Z
Comments.Text: Sorry, I should have specified. It is a plain text field in the CP.
  Users are presented a drop-down list of years on their profile page that populates `myYearField` within the CP.
Comments.UserDisplayName: Damon
Tags: <templating><entries>
Title: How can I group entries based on a string value?
ThreadText: # How can I group entries based on a string value?
  
  (Asked by: username_0 on 2016-10-17)
  
  I have been able to successfully [group entries via dateTime field](https://craftcms.stackexchange.com/questions/16748/how-can-i-group-entries-based-on-a-datetime-field). I have been trying to carry over the same type of logic only instead of using `.date` just key off of the field value.
  
  ```
  {# Get all entries from the section. #}
  {% set entries = craft.entries.section('mySection') %}
  
  {# Loop through the entries and get the user account associated with each. #}
  {% for profiles in entries %}
      {% set users = profiles.userAccount %}
  
      {% if users|length %}
          {% for year, user in users|group('myYearField') %}
              <h4>{{ year }}</h4> {# 2016 #}
              <ul class="list-unstyled">
                  {% for user in users %}
                      <li><a href="{{ profiles.url }}">{{ user.name }}</a></li>
                  {% endfor %}
              </ul>
          {% endfor %}
      {% endif %}
  {% endfor %}
  
  ```
  
  Currently what I am getting is:
  
  ```
  2016
      User
  2016
      User
  ...
  
  ```
  
  What I am trying to get (I swear I had this working at one point) is this:
  
  ```
  2016
      User
      User
  
  2017
     User
     User
  
  ```
  
  **EDIT**
  
  It seems my trouble comes from not accessing the `users` field correctly.
  Updated (but still incorrect) example:
  
  ```
  {% set allProfiles = craft.entries.section('mySection') %}
  {% if allProfiles|length %}
      {{ allProfiles|length }} {# 3 #}
      {% for profiles in allProfiles %}
          {% for profile in profiles.userAccount %}
              {% for year, user in profile|group('yearFieldHandle') %}
                  <h1>{{ year }}</h1>  {# No output #}
                  <h2>{{ profile.firstName }}</h2>    {# Bob #}
                  <h3>{{ profile.myYear }}</h3> {# 2016 #}
              {% endfor %}
          {% endfor %}
      {% endfor %}
  {% endif %}
  
  ```
  
  **Tags:** templating, entries
  
  > **Comments:**
  > **username_1**: To be clear, is `myYearField` a DateTime or PlainText field?  
  > **username_0**: Sorry, I should have specified. It is a plain text field in the CP. Users are presented a drop-down list of years on their profile page that populates `myYearField` within the CP.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2016-10-18. Score: 7 | Accepted answer
  
  There’s a lot to unpack here. Before I get to the solution, I’ll step through each of your examples, line-by-line. Hopefully that will help explain the behavior you’re seeing.
  
  ## First Example
  
  ```
  {# Get all entries from the section. #}
  {% set entries = craft.entries.section('mySection') %}
  
  ```
  
  Your comment is correct – this will fetch all the entries from section `mySection` and assign them to a new variable called `entries`.
  
  ```
  {# Loop through the entries and get the user account associated with each. #}
  {% for profiles in entries %}
  
  ```
  
  Start a loop on the `entries` variable. Within the loop, each profile entry will be represented by a `profiles` variable.
  
  *Note: it’s misleading to call your variable “profiles” rather than “profile”, since it will only represent a single profile entry.*
  
  ```
      {% set users = profiles.userAccount %}
  
  ```
  
  Fetch all of the user accounts related to the current profile (`profiles`) via the `userAccount` field, and assign them to a new variable called `users`.
  
  ```
      {% if users|length %}
  
  ```
  
  Only do the following if there were any related users…
  
  ```
          {% for year, user in users|group('myYearField') %}
  
  ```
  
  Turn the users (`users`) that are related to the current profile (`profiles`) into a multi-dimensional array, grouped by their `myYearField` field values. Then start a loop on that multi-dimensional array. Within the loop, each `myYearField` value will be represented by a `year` variable, and the array of grouped user accounts will be represented by a `user` variable.
  
  *Note: This is where things start really going wrong. You want to group **all** of your users by year – not just the ones that are related to the current profile. Also, your choice of “user” as a variable name here is misleading since it’s actually an array of grouped users; not a single user.*
  
  ```
              <h4>{{ year }}</h4> {# 2016 #}
  
  ```
  
  Output the current grouping’s `myYearField` value, which was assigned to a `year` variable.
  
  ```
              <ul class="list-unstyled">
                  {% for user in users %}
  
  ```
  
  Start a loop on the same `users` variable that you’re already in the middle of looping through. `users` here refers to the same `users` variable that was defined in the 3rd codeblock.
  
  ```
                      <li><a href="{{ profiles.url }}">{{ user.name }}</a></li>
  
  ```
  
  Output the profile entry’s (`profiles`) URL, and the current user’s (`user`) name.
  
  ```
                  {% endfor %}
  
  ```
  
  Close out the loop on the user accounts related to the current profile entry (`users`).
  
  ```
              </ul>
          {% endfor %}
  
  ```
  
  Close out the loop on the multi-dimensional array of year-user groupings based on the user accounts related to the current profile entry (`users`).
  
  ```
      {% endif %}
  
  ```
  
  Close out the conditional checking if there any users related to the current profile entry.
  
  ```
  {% endfor %}
  
  ```
  
  Close out the loop on the profile entries (`entries`).
  
  ---
  
  ## Second Example
  
  ```
  {% set allProfiles = craft.entries.section('mySection') %}
  
  ```
  
  Fetch all the entries from section `mySection` and assign them to a new variable called `allProfiles`.
  
  ```
  {% if allProfiles|length %}
  
  ```
  
  Only do the following if there were any profile entries…
  
  ```
      {{ allProfiles|length }} {# 3 #}
  
  ```
  
  Output the total number of profile entries.
  
  ```
      {% for profiles in allProfiles %}
  
  ```
  
  Start a loop on the `allProfiles` variable. Within the loop, each profile entry will be represented by a `profiles` variable.
  
  *Note: as with the last example, it’s misleading to call your variable “profiles” rather than “profile”, since it will only represent a single profile entry.*
  
  ```
          {% for profile in profiles.userAccount %}
  
  ```
  
  Fetch all of the user accounts related to the current profile (`profiles`) via the `userAccount` field. Start a loop on the user accounts. Within the loop, each user account will be represented by a `profile` variable.
  
  *Note: it’s misleading to call your variable “profile”, since it is actually the user account, not the profile entry.*
  
  ```
              {% for year, user in profile|group('yearFieldHandle') %}
  
  ```
  
  Turn the current user account (`profile`) into a multi-dimensional array, grouped by its properties’ `yearFieldHandle` sub-property values (which isn’t a thing). Then start a loop on that multi-dimensional array. Within the loop, each `yearFieldHandle` value will be represented by a `year` variable, and the array of grouped user account properties will be represented by a `user` variable.
  
  *Note: Since `profile` is a single element (the user account) and not an array of elements, nothing about this is likely doing what you expected it to.*
  
  ```
                  <h1>{{ year }}</h1>  {# No output #}
  
  ```
  
  Output the current grouping’s `yearFieldHandle` value, which was assigned to a `year` variable. (This is the equivalent of doing something like `profile.id.yearFieldHandle`. It’s expected that you wouldn’t get any output.)
  
  ```
                  <h2>{{ profile.firstName }}</h2>    {# Bob #}
  
  ```
  
  Output the user account’s first name.
  
  ```
                  <h3>{{ profile.myYear }}</h3> {# 2016 #}
  
  ```
  
  Output the user account’s `myYear` custom field value.
  
  ```
              {% endfor %}
  
  ```
  
  Close out the loop on the multi-dimensional array of year-user account property groupings based on the current user account defined by the parent loop.
  
  ```
          {% endfor %}
  
  ```
  
  Close out the loop on the user accounts related to the current profile entry.
  
  ```
      {% endfor %}
  
  ```
  
  Close out the loop on the profile entries (`allProfiles`).
  
  ```
  {% endif %}
  
  ```
  
  Close out the conditional checking if there any profile entries.
  
  ---
  
  ## Solution
  
  To group all of your profiles by their related user accounts’ custom date fields, first let’s load the profiles, [eager-loaded](https://craftcms.com/docs/templating/eager-loading-elements) with their related user accounts:
  
  ```
  {% set profiles = craft.entries({
      section: 'userProfiles',
      with: ['userAccount']
  }) %}
  
  ```
  
  Next let’s group the profiles by the `myYear` custom field on their related user accounts:
  
  ```
  {% set profilesByYear = profiles|group('userAccount[0].myYear') %}
  
  ```
  
  Now we can loop through the years, and their corresponding user profiles/accounts:
  
  ```
  {% for year, yearProfiles in profilesByYear %}
      <h1>{{ year }}</h1>
  
      {% for profile in yearProfiles %}
          {% set user = profile.userAccount[0] ?? null %}
          {% if user %}
              <h2>{{ user.firstName }}</h2>
              <h3>{{ user.myYear }}</h3>
          {% endif %}
      {% endfor %}
  {% endfor %}
  
  ```
  
  > **Comments:**
  > **username_0**: This is a fantastic response. Thank you for taking the time to write this all out!  
  
  ---
  
  