Since I have started working on DeHL, one of the main purposes was to get to the point where I could use *Linq*-like extensions on collection classes. Of course I could not call the new functionality *Linq* since it’s not language-integrated, so I decided to give it another name: **Enex** (aka **Enumerable Extensions**). All collection classes in DeHL now support a wide set of methods that allow querying and selecting elements from the starting collection. A lot of work has been put into this release, ranging from extensions to type system, object life-time management, optimizations and bug-fixes and of course a lot of testing.

### Now, back to Enex, let’s visit some cool examples of what the new functionality can do:

Let’s check a very simple example. Assuming you have a list of integers and you want to find the sum of all elements that are greater than the list average. In the “times before” you wold write something like this:

{ Calculate the average of the list }
Sum := 0;
for I := 0 to List.Count - 1 do
Sum := Sum + List[I];
Avg := Sum div List.Count;
{ Calculate the sum of the elements above average }
Sum := 0;
for I := 0 to List.Count - 1 do
if List[I] > Avg then
Sum := Sum + List[I];

… Now it is as simple as this:

{ ... }
Sum := List.WhereGreater(List.Average()).Sum();
{ ... }

Now, let’s see another more complex example. Considering that you have two collections of integers. You have to determine the maximum value common to both collections. Check it out:

{ ... }
Max := AColl1.Intersect(AColl2).Max();
{ ... }

Next: what is the sum of all odd numbers in interval [0..100]?

Sum := TEnexEnumerable<Integer>
.Interval(0, 100)
.Where(function(Arg1: Integer): Boolean
begin
Exit(Odd(Arg1);
end)
.Sum();

The last one: You want to take all integers from a list with their absolute value and only once; and you want to write them on the screen directly:

for I in ARandomList
.Select(function(Arg1: Integer): Integer
begin
Exit(Abs(Arg1));
end)
.Distinct()
do
WriteLn(I);

What’s working and what’s not:

- Some problems in the compiler prevent the use of generic function
*Select<TOut>* and *Cast<TOut>* for now. These two could have been used to transform each element of the collection to some other type.
- Everything is based in interfaces to make use of automatical garbage collection. the only restriction is that the first enumerable (from which the chain starts) should be either an interface or must be destroyed explicitly.
- All collections have overriden versions of some functions. For example in a list, the
*First()* method is implemeted directly so that you benefit from full speed whenever possible.
- No lambdas … that makes writing selectors or predicates rather unpleasant.
*Sum()* and *Average()* are only supported for types registered as integers or reals (including BigCardinal and BigInteger).
- All selector and predicate-based selection is done on-the fly so there is no additional memory used!

There are of course much more possible use cases for **Enex**-enabled collections, I simply do not have the time to list all of them.

**You can download the latest version of DeHL here.**