2

We are building a family community website with 600+ members.

One of the gimmicks will be some stats, like average age all members.

Is there a smart way to calculate this?

2
{# Get all members #}
{% set members = craft.users().limit(null) %}

{# Get total number of members #}
{% set memberCount = members.total() %}

{# Set this outside the 'for' loop so you can use it later #}
{% set ageSum = 0 %}

{# Add 'em up #}
{# We assume here you have a custom member field with the handle 'age' #}
{% for member in members %}
    {% set ageSum = ageSum + member.age %} 
{% endfor %}

{# Get the average #}
{% set avgAge = ageSum / memberCount %}

{# Print it #}
<p>Average member age is {{ avgAge }}<p>

If you want to limit the calculation to a particular user group, just add its handle to the end of the first set.

{% set members = craft.users().group('groupHandle') %}

If age is not a required field you might want to skip records that don't have an age. I'm not entirely sure what including them would do to the math.

{% set ageSum = (member.age and member.age > 0) ? ageSum + member.age : ageSum %}
  • Philip, in your example you don't add .limit(x) to it. If I leave that out, I only get 100 results. Is there a way to disable this default limit of 100? – John Stevens Sep 28 '16 at 19:29
  • 1
    @JohnStevens, you can add .limit(null) to the criteria in order to return all users – i.e. {% set members = craft.users().limit(null) %}. – Mats Mikkel Rummelhoff Sep 28 '16 at 19:45
  • Actually, I'll edit the question to include it :) – Mats Mikkel Rummelhoff Sep 28 '16 at 19:45
  • I also made the assumption of an age field, versus the far more logical birthdate field. But it should be easy enough to replace all my age field references with an age calculation based on the birthdate. – Philip Jones Sep 30 '16 at 16:26
  • And thanks @MatsMikkelRummelhoff for updating with .limit(null). I always forget to account for the 100-record limit. Good call. – Philip Jones Sep 30 '16 at 16:28
2

I don't think this will exactly answer your question, but I think it will help get you going in the right direction.

Within my application, I am grabbing entries that belong to the currently logged in user - finding the fields and then displaying an average distance.

If you'll notice I am setting a level': 2 in my parameters. That's because I am working with a structure and the first level is the "parent" entry that does not have any of the data I am attempting to average.

{# Get all of the entries entered by the user. #}
{% set entries = craft.entries({
    'section': 'mySection',
    'level': 2,
    'descendantOf': user.id
}) %}

{% if entries|length %}

    ...

    {% set value = 0 %}
    {% set count = 0 %}

    {% for entry in entires %}
        {% set value = value + entry.distance %}
        {% set count = loop.index %}
    {% endfor %}

    {% set averageDistance = (value / count)|round(1, 'floor') %}

    <p>Avg: {{ averageDistance }}</p>

    ...

{% else %}
    {# Could not find any entries. #}
{% endif %}

So in a nutshell, you'll want to:

  • grab the entries from the appropriate section
  • find the field(s) you want to average ex: distance
  • do math
  • return the result

For you (this is a stab in the dark) you would want to get all users, get the value of the age field. Then loop over to get your count and divide that by the ages.

Hope this helps!

  • Thanks Damon, your example gave me insight on how to do it. {% set totaal = craft.users.group('leden').limit(5000)|length %} {% set sumage = 0 %} {% for age in craft.users.group('leden').limit(5000) %} {% set sumage = sumage + age.geboortedatum.diff(now).format('%y') %} {% endfor %} Avg: {{ (sumage / totaal)|round }} – John Stevens Sep 28 '16 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.