<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>

CC BY-SA 3.0
2016-08-01T18:40:00.620Z
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!
Erik
CC BY-SA 3.0
2016-08-02T08:03:29.773Z
Is it in the same category group? Have you checked there are any related entries returned?
Luke Pearce
CC BY-SA 3.0
2016-08-02T12:24:57.787Z
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.
Erik
CC BY-SA 3.0
2016-08-02T13:15:34.230Z
@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.
Luke Pearce
CC BY-SA 3.0
2016-08-02T13:25:35.773Z
Hmm... it works though. Test my code.
Erik
CC BY-SA 3.0
2016-08-02T13:35:47.137Z
Ignore me.. I originally had to test with products not entries. Your code works ;)
Luke Pearce
CC BY-SA 3.0
2016-08-02T13:36:50.453Z
Awesome! I marked yours as the answer with my edit. Thanks again!
Erik
CC BY-SA 3.0
2016-08-01T18:00:41.607Z
2016-08-02T13:41:03.133Z
2016-08-02T13:41:03.133Z
Luke Pearce
<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>

<templating>
Get Entries within a Category Group with no duplicates in each category
# 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' ) %}
      {{ category.title }}

      // 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 }}
      {% endfor %}
    {% endfor %}


UPDATE:
Erik 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**: @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.  
> **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!  

---

