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:
- Filters employees over 25 years old
- Sorts them by name
- Takes the first 10 results
- Selects only their names
Best Practices
- Use predicates efficiently - Filter data as early as possible in the chain
- Avoid complex expressions - Break down complex logic into multiple steps
- Test with sample data - Verify enumeration methods work with your data structure
- Handle empty collections - Use
Any()to check before processing collections - Optimize performance - Minimize enumeration method calls in loops
When working with large data collections, consider filtering and limiting data at the source rather than in the template for better performance.