## DEV Community

Rob Mulpeter

Posted on • Updated on

# Manipulating Collections in F# - Basic Examples

This article is to provide you with some basic examples of collection manipulation in `F#` run from a `console application` in `.NET 6`. The examples are drawn heavily from a series of exercises in `Stylish F# 6: Crafting Elegant Functional Code for .NET 6, 2nd Edition, 2021` by `Kit Eason`.

In order to run the examples you will need to add some initial utility functions and types to the top of your `program.fs` file.

``````type Car =
{ Model : string
Price : decimal }

type PriceBand = | Cheap | Medium | Expensive

module FakeData =

let private random = System.Random(Seed = 1)

/// Make an array of 'count' number of random houses.
let getRandomArrayOfCars (count: int) =
Array.init count (fun i ->
{ Model = \$"Model %i{i+1}"
Price = random.Next(10_000, 150_000) |> decimal })

/// Try to get the distance to the nearest garage.
/// While the 'Car' parameter is not used we add it to change the signature
/// Allowing us to pipe into it later with a Car object
let tryGetDistanceToGarage (car: Car) =
let dist = random.Next(30) |> double
if dist < 20 then
Some dist
else
None

// Return a price band based on price.
let getPriceCategory (price : decimal) =
if price < 40_000m then
Cheap
elif price < 100_000m then
Medium
else
Expensive

module Array =
let inline tryAverageBy f (a : 'T[]) =
if a.Length = 0 then
None
else
let average = a |> Array.averageBy f |> decimal
System.Math.Round(average, 2) |> Some
``````

Then you can add the below examples and execute them with `dotnet run`.

``````// Transforming Data Items
let getCarListing =
printfn "\n------ TRANSFORMING DATA ------"
FakeData.getRandomArrayOfCars 3
|> Array.map (fun h ->
printfn \$"Model: {h.Model} - Price: {h.Price}")

// Calculating an Average
let getAverageCarPrice =
printfn "\n-------- AVERAGE PRICE --------"
let price = FakeData.getRandomArrayOfCars 10
|> Array.averageBy (fun c -> c.Price)
printfn \$"Average price: {price}"

// Selecting Based on Condition, Order and iteration
let getExpensiveCars =
printfn "\n------- EXPENSIVE CARS --------"
FakeData.getRandomArrayOfCars 10
|> Array.filter (fun c -> c.Price > 100_000m)
|> Array.sortByDescending (fun c -> c.Price)
|> Array.iter (fun c ->
printfn \$"Model: {c.Model} - Price: {c.Price}")

// Finding a Single Element
let getCarWithDistanceToGarage =
printfn "\n- CAR WITH DISTANCE TO GARAGE -"
let result = FakeData.getRandomArrayOfCars 1
|> Array.tryPick (fun c ->
match c |> FakeData.tryGetDistanceToGarage with
| Some d -> Some(c, d)
| None -> None)
printfn \$"{result}"

let getCarsByPriceCategory =
printfn "\n--- CAR WITH PRICE CATEGORY ---"
let result = FakeData.getRandomArrayOfCars 6
|> Array.groupBy (fun c -> c.Price |> FakeData.getPriceCategory)
|> Array.map (fun group ->
let category, cars = group
category, cars |> Array.sortBy (fun c -> c.Price))
printfn \$"{result[0]}"

let tryGetAverageCarPriceOver100K =
printfn "\n--- AVERAGE PRICE OVER 100K ---"
let result = FakeData.getRandomArrayOfCars 20
|> Array.filter (fun h -> h.Price > 100_000m)
|> Array.tryAverageBy (fun h -> h.Price)
printfn \$"{result}"
``````

Output

``````------ TRANSFORMING DATA ------
Model: Model 1 - Price: 44813
Model: Model 2 - Price: 25504
Model: Model 3 - Price: 75381

-------- AVERAGE PRICE --------
Average price: 73004.4

------- EXPENSIVE CARS --------
Model: Model 1 - Price: 148567
Model: Model 8 - Price: 142968
Model: Model 6 - Price: 108595
Model: Model 7 - Price: 108251
Model: Model 2 - Price: 105497
Model: Model 3 - Price: 101684

- CAR WITH DISTANCE TO GARAGE -
Some(({ Model = "Model 1"
Price = 63475M }, 15))

--- CAR WITH PRICE CATEGORY ---
(Cheap, Program+Car[])

--- AVERAGE PRICE OVER 100K ---
Some(120609.44)
``````