Answers.Body: <p>I've tested this with some of my own content and believe it works to your spec. You need to keep a track of all entries that have been displayed so far. You then loop through each categories related entries and if the entry hasn't been shown in a previous category we add it to a new array within that category loop.</p>
  
  <pre><code>    // Set empty array to hold id's of all currently displayed entries
      {% set entries_displayed = [] %}
  
      // Loop over a category group
      {% for category in craft.categories.group( 'productBrand' ) %}
        &lt;h2&gt;{{ category.title }}&lt;/h2&gt;
  
        // Get related entries to the category
        {% set related_entries = craft.entries.relatedTo( category ) %}
  
        // Set empty array to hold id's of entries we'll eventually output
        {% set entries_to_display = [] %}
  
        // Loop through related entries
        {% for entry in related_entries %}
  
          // If the entry hasn't been displayed
          {% if entry.id not in entries_displayed %}
  
            // We want to show the entry
            {% set entries_to_display = entries_to_display|merge([entry.id]) %}
          {% endif %}
        {% endfor %}
  
        // Finally grab the entries to display from the array of id's that haven't already been shown
        {% set entries = craft.entries.id( entries_to_display ).limit( 4 ) %}
        {% for entry in entries %}
  
          // Add the id to our "already displayed" array
          {% set entries_displayed = entries_displayed|merge([entry.id]) %}
  
          {{ entry.id }} - {{ entry.title }}&lt;br&gt;
        {% endfor %}
      {% endfor %}
  </code></pre>
  
  <hr>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Erik later discovered an error in my original answer where I was setting <code>entries_displayed</code> in the first <code>for</code> loop before they'd actually been output in the last <code>for</code> loop. I've updated the code to reflect his fix.</p>
  
  <blockquote>
    <p>I had to move the <code>entries_displayed</code> array to the last <code>for</code> loop which displayed the entries. That way I knew exactly what entries had been displayed. If I didn't do that, it would assume more than 4 were shown per category.</p>
  </blockquote>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-01T18:40:00.620Z
Answers.Text: This is so close! For some reason, one category doesn't get any entries. There are 4 categories and the 3rd is the issue. There are no expiration dates and all the entries are live. I can't imagine what the issue may be. Thank you btw!
Answers.UserDisplayName: Erik
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-02T08:03:29.773Z
Answers.Text: Is it in the same category group? Have you checked there are any related entries returned?
Answers.UserDisplayName: Luke Pearce
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-02T12:24:57.787Z
Answers.Text: I believe I figured it out. I will post an update with my code. I moved the `entries_displayed` array to the last for loop which displays the entries. By doing that, I'm guaranteeing only the ones displayed get merged into that array.
Answers.UserDisplayName: Erik
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-02T13:15:34.230Z
Answers.Text: @Erik - The problem with that is that there are no initial entries to show because `entries_to_display` is empty. I will test with the limit 4 issue and update my answer.
Answers.UserDisplayName: Luke Pearce
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-02T13:25:35.773Z
Answers.Text: Hmm... it works though. Test my code.
Answers.UserDisplayName: Erik
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-02T13:35:47.137Z
Answers.Text: Ignore me.. I originally had to test with products not entries. Your code works ;)
Answers.UserDisplayName: Luke Pearce
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-02T13:36:50.453Z
Answers.Text: Awesome! I marked yours as the answer with my edit. Thanks again!
Answers.UserDisplayName: Erik
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-08-01T18:00:41.607Z
Answers.LastActivityDate: 2016-08-02T13:41:03.133Z
Answers.LastEditDate: 2016-08-02T13:41:03.133Z
Answers.UserDisplayName: Luke Pearce
Body: <p>How would I loop through all categories in a group to get this scenario: </p>
  
  <ul>
  <li>Get 4 entries per category</li>
  <li>No duplicates across any of the categories, if it's in Cat 1, should not show in any other.</li>
  <li>Category info (title, URL, etc)</li>
  </ul>
  
  <p>So here is a visual:</p>
  
  <p>Category 1</p>
  
  <ul>
  <li>Entry 1</li>
  <li>Entry 2</li>
  <li>Entry 3</li>
  <li>Entry 4</li>
  </ul>
  
  <p>Category 2</p>
  
  <ul>
  <li><strike>Entry 1</strike> (duplicate from Category 1, do not want here, so get 4 different)</li>
  <li>Entry 5</li>
  <li>Entry 6</li>
  <li>Entry 7</li>
  <li>Entry 8</li>
  </ul>
  
  <p>Category 3</p>
  
  <ul>
  <li><strike>Entry 2</strike> (duplicate from Category 1, do not want here, so get 4 different)</li>
  <li><strike>Entry 6</strike> (duplicate from Category 2, do not want here, so get 4 different)</li>
  <li>Entry 9</li>
  <li>Entry 10</li>
  <li>Entry 11</li>
  <li>Entry 12</li>
  </ul>
  
  <p>I hope this gives a decent visual of what I want.</p>
  
Tags: <templating>
Title: Get Entries within a Category Group with no duplicates in each category
ThreadText: # Get Entries within a Category Group with no duplicates in each category
  
  (Asked by: username_0 on 2016-08-01)
  
  How would I loop through all categories in a group to get this scenario:
  
  * Get 4 entries per category
  * No duplicates across any of the categories, if it's in Cat 1, should not show in any other.
  * Category info (title, URL, etc)
  
  So here is a visual:
  
  Category 1
  
  * Entry 1
  * Entry 2
  * Entry 3
  * Entry 4
  
  Category 2
  
  * Entry 1 (duplicate from Category 1, do not want here, so get 4 different)
  * Entry 5
  * Entry 6
  * Entry 7
  * Entry 8
  
  Category 3
  
  * Entry 2 (duplicate from Category 1, do not want here, so get 4 different)
  * Entry 6 (duplicate from Category 2, do not want here, so get 4 different)
  * Entry 9
  * Entry 10
  * Entry 11
  * Entry 12
  
  I hope this gives a decent visual of what I want.
  
  **Tags:** templating
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2016-08-01. Score: 2 | Accepted answer
  
  I've tested this with some of my own content and believe it works to your spec. You need to keep a track of all entries that have been displayed so far. You then loop through each categories related entries and if the entry hasn't been shown in a previous category we add it to a new array within that category loop.
  
  ```
      // Set empty array to hold id's of all currently displayed entries
      {% set entries_displayed = [] %}
  
      // Loop over a category group
      {% for category in craft.categories.group( 'productBrand' ) %}
        <h2>{{ category.title }}</h2>
  
        // Get related entries to the category
        {% set related_entries = craft.entries.relatedTo( category ) %}
  
        // Set empty array to hold id's of entries we'll eventually output
        {% set entries_to_display = [] %}
  
        // Loop through related entries
        {% for entry in related_entries %}
  
          // If the entry hasn't been displayed
          {% if entry.id not in entries_displayed %}
  
            // We want to show the entry
            {% set entries_to_display = entries_to_display|merge([entry.id]) %}
          {% endif %}
        {% endfor %}
  
        // Finally grab the entries to display from the array of id's that haven't already been shown
        {% set entries = craft.entries.id( entries_to_display ).limit( 4 ) %}
        {% for entry in entries %}
  
          // Add the id to our "already displayed" array
          {% set entries_displayed = entries_displayed|merge([entry.id]) %}
  
          {{ entry.id }} - {{ entry.title }}<br>
        {% endfor %}
      {% endfor %}
  
  ```
  
  ---
  
  **UPDATE:**
  
  username_0 later discovered an error in my original answer where I was setting `entries_displayed` in the first `for` loop before they'd actually been output in the last `for` loop. I've updated the code to reflect his fix.
  
  > I had to move the `entries_displayed` array to the last `for` loop which displayed the entries. That way I knew exactly what entries had been displayed. If I didn't do that, it would assume more than 4 were shown per category.
  
  > **Comments:**
  > **username_0**: This is so close! For some reason, one category doesn't get any entries. There are 4 categories and the 3rd is the issue. There are no expiration dates and all the entries are live. I can't imagine what the issue may be. Thank you btw!  
  > **username_1**: Is it in the same category group? Have you checked there are any related entries returned?  
  > **username_0**: I believe I figured it out. I will post an update with my code. I moved the `entries_displayed` array to the last for loop which displays the entries. By doing that, I'm guaranteeing only the ones displayed get merged into that array.  
  > **username_1**: @username_0 - The problem with that is that there are no initial entries to show because `entries_to_display` is empty. I will test with the limit 4 issue and update my answer.  
  > **username_0**: Hmm... it works though. Test my code.  
  > **username_1**: Ignore me.. I originally had to test with products not entries. Your code works ;)  
  > **username_0**: Awesome! I marked yours as the answer with my edit. Thanks again!  
  
  ---
  
  