Calculate average, total or price (including tax) are common tasks in any business application. Collections are an easy way to aggregate your data in a consistent way. With it, this type of calculation becomes very simple, because there are collection methods that do everything for you!
This article is part of a series demonstrating how to manipulate collections using the methods added in 4D v16 R6. To learn even more, download our database example, which includes 12 different examples to show all you can do with collection methods!
Database example: Manage collections
sum, average, min and max
You can calculate the sum of all values in a collection with the sum method:
// Calculate sum of all elements in a collection of numeric values
$col:=New collection(10000;50000;10500.5)
$vSum:=$col.sum() //$vSum=70500.5
// Calculate sum of all elements in a collection of objects
$col:=New collection("name";"Smith";"salary";10000)
$col.push(New object("name";"Wesson";"salary";50000))
$col.push(New object("name";"Gross";"salary";10500.5))
$vSum:=$col.sum("salary") //$vSum=70500.5
You can also calculate the average, min and max in the same way, with collection methods of the same name.
The average method returns the arithmetic mean (average) of all collection values:
$col:=New collection(10000;50000;10500.5)
$vAvg:=$col.average() // $vAvg=23500.16666667
The min method returns the element with the smallest value in the collection:
$col:=New collection(10000;50000;10500.5)
$vMin:=$col.min() // $vMin=10000
The max method returns the element with the highest value in the collection:
$col:=New collection(10000;50000;10500.5)
$vMax:=$col.max() // $vMax=50000
Count elements in a collection
If you want to know the number of elements that a collection contains, just use count to find the number of non-null elements and length for total number of elements.
$col:=New collection(1;2;3;Null;"a";"b";Null)
$length:=$col.length // $length=7 length is an attribute
$count:=$col.count() // $count=5 count is a method
You can also count the number of times a specific value is used in your collection using countValues:
$col:=New collection(1;2;5;5;5;3;6;4)
$vCount:=$col.countValues(5) // $vCount=3
Specific calculations
Two other collection methods allow you to apply a call back on all elements of a collection. Basically, the callback method is one of your project methods. No need for you to write a loop, 4D takes care of it for you:
The map method applies the call back on each element of the collection and returns a collection with all the new elements. For example, if you need to calculate the percentage for each number in a collection according to the sum total, it’s easy using map:
$c:=New collection(1;4;9;10;20)
$c2:=$c.map("Percentage";$c.sum()). // use Percentage as call back method
//$c2=[2.27,9.09,20.45,22.73,45.45]
where Percentage is a project method as follows:
$1.result:=Round(($1.value/$2)*100;2)
The reduce method applies a callback against an accumulator and each element in the collection (from left to right) to reduce it to a single element. For example, in a collection with several mixed products, you may want to calculate the tally of each product. The reduce method makes it very simple:
$fruits:=New collection("banana"; "cherry"; "orange"; "apple"; "cherry"; "orange"; "apple"; "banana"; "cherry"; "orange"; "fig" )
$count:=$fruits.reduce("Tally";New object) // use Tally as call back method
//$count={banana:2,cherry:3,orange:3,apple:2,fig:1}
where Tally is a project method as follows:
// Search if a fruit with this name already exists in the accumulator collection
If ($1.accumulator[$1.value]#Null)
$1.accumulator[$1.value]:=$1.accumulator[$1.value]+1
Else
// If it doesn't already exist, create a new fruit
$1.accumulator[$1.value]:=1
End if