Skip to main content

Enumeration in Templates - Data Methods Guide

PDF4me's document generation engine provides powerful enumeration methods for manipulating data collections within templates. These methods, similar to C# IEnumerable, offer comprehensive control over data operations including sorting, filtering, aggregation, and transformation.


Available Enumeration Methods

The following methods can be applied to collections within your templates to process and manipulate data dynamically:

Filtering and Validation Methods

All(Predicate) - Determines whether all elements satisfy a condition

[employees.All(p => p.Age < 50)]

Any() - Determines whether a collection contains any elements

employees.Any()

Any(Predicate) - Determines whether any element satisfies a condition

employees.Any(p => p.Name == "Mary Doe")

Contains(Object) - Determines whether a collection contains a specific element

employees.Contains(otherPersons.First())

Aggregation Methods

Average(Selector) - Computes the average of a numeric collection

employees.Average(p => p.Age)

Count() - Returns the number of elements in a collection

employees.Count()

Count(Predicate) - Returns the number of elements that satisfy a condition

employees.Count(p => p.Age > 30)

Max(ComparableSelector) - Returns the maximum value in a collection

employees.Max(p => p.Age)

Min(ComparableSelector) - Returns the minimum value in a collection

employees.Min(p => p.Age)

Sum(Selector) - Computes the sum of numeric values in a collection

employees.Sum(p => p.Children.Count())

Selection and Projection Methods

First() - Returns the first element of a collection

employees.First()

First(Predicate) - Returns the first element that satisfies a condition

employees.First(p => p.Age > 30)

FirstOrDefault() - Returns the first element, or a default value if empty

employees.FirstOrDefault()

FirstOrDefault(Predicate) - Returns the first element that satisfies a condition, or default

employees.FirstOrDefault(p => p.Age > 30)

Last() - Returns the last element of a collection

employees.Last()

Last(Predicate) - Returns the last element that satisfies a condition

employees.Last(p => p.Age > 100)

LastOrDefault() - Returns the last element, or a default value if empty

employees.LastOrDefault()

LastOrDefault(Predicate) - Returns the last element that satisfies a condition, or default

employees.LastOrDefault(p => p.Age > 100)

Single() - Returns the only element of a collection

employees.Single()

Single(Predicate) - Returns the only element that satisfies a condition

employees.Single(p => p.Name == "John Smith")

SingleOrDefault() - Returns the only element, or a default value if empty

employees.SingleOrDefault()

SingleOrDefault(Predicate) - Returns the only element that satisfies a condition, or default

employees.SingleOrDefault(p => p.Name == "Mary Doe")

Ordering Methods

OrderBy(ComparableSelector) - Sorts elements in ascending order

employees.OrderBy(p => p.Age)

Can be chained with additional ordering:

employees.OrderBy(p => p.Age).ThenByDescending(p => p.Name)

OrderByDescending(ComparableSelector) - Sorts elements in descending order

employees.OrderByDescending(p => p.Age)

Can be chained with additional ordering:

employees.OrderByDescending(p => p.Age).ThenByDescending(p => p.Name)

Collection Operations

Concat(IEnumerable) - Concatenates two collections

employees.Concat(otherPersons)

Distinct() - Returns distinct elements from a collection

employees.Distinct()

Union(IEnumerable) - Produces the set union of two collections

employees.Union(otherPersons)

Where(Predicate) - Filters elements based on a condition

employees.Where(p => p.Age > 18)

Set Operations

Skip(int) - Bypasses a specified number of elements

employees.Skip(10)

SkipWhile(Predicate) - Bypasses elements as long as a condition is true

employees.SkipWhile(p => p.Age < 35)

Take(int) - Returns a specified number of elements

employees.Take(5)

TakeWhile(Predicate) - Returns elements as long as a condition is true

employees.TakeWhile(p => p.Age < 50)

Transformation Methods

Select(Selector) - Projects each element into a new form

employees.Select(p => p.Name)

SelectMany(EnumerationSelector) - Projects and flattens collections

employees.SelectMany(p => p.Children)

GroupBy(Selector) - Groups elements by a specified key

employees.GroupBy(p => p.Age)

Can group by multiple properties:

employees.GroupBy(p => new { Age = p.Age, Count = p.Children.Count() })

Practical Examples

Example 1: Filtering and Counting

Template:

Total employees over 30: <<[employees.Count(p => p.Age > 30)]>>
Average age: <<[employees.Average(p => p.Age)]>>

Example 2: Conditional Display

Template:

<<if [employees.Any(p => p.Age > 50)]>>
We have senior employees in the team.
<</if>>

Example 3: Sorted Lists

Template:

<<foreach [emp in employees.OrderBy(p => p.Name)]>>
- <<[emp.Name]>> (Age: <<[emp.Age]>>)
<</foreach>>

Example 4: Grouped Data

Template:

<<foreach [group in employees.GroupBy(p => p.Department)]>>
Department: <<[group.Key]>>
Employee Count: <<[group.Count()]>>
<</foreach>>

Method Chaining

Multiple enumeration methods can be chained together for complex data operations:

<<[employees
.Where(p => p.Age > 25)
.OrderBy(p => p.Name)
.Take(10)
.Select(p => p.Name)]>>

This expression:

  1. Filters employees over 25 years old
  2. Sorts them by name
  3. Takes the first 10 results
  4. Selects only their names

Best Practices

  1. Use predicates efficiently - Filter data as early as possible in the chain
  2. Avoid complex expressions - Break down complex logic into multiple steps
  3. Test with sample data - Verify enumeration methods work with your data structure
  4. Handle empty collections - Use Any() to check before processing collections
  5. Optimize performance - Minimize enumeration method calls in loops
Performance Consideration

When working with large data collections, consider filtering and limiting data at the source rather than in the template for better performance.