Today we learn Sequence, represents an ordered, read-only series of elements
Why Sequence
- Sequences are particularly useful when you have a large, ordered collection of data but do not necessarily expect to use all of the elements.
- Individual sequence elements are computed on-demand, so a sequence can provide better performance than a list in situations in which not all the elements are used
What is computed on-demand
like buying a burger in KFC, the staff prepared 1000 burgers in the early morning, so you got your burger immediately, all the burgers are made before customer order, this is called eager evaluation
then you ordered a fried chicken, the staff replies: sorry, you have to wait for a minute, as we need to fry the chicken first, they only do the work when someone ordered, this is called lazy evaluation, also known as On-demand computation
Create Sequence
- Explicitly specifying elements
let seq1 = seq [1; 2; 3; 4]
printfn "seq: %A" seq1
- Using range expression
let seq1 = seq { 1 .. 10 } // from 1 to 10
printfn "seq: %A" seq1 // seq: seq [1; 2; 3; 4; ...]
use step in range expression
let seq1 = seq { 1 .. 2 .. 10 } // start from 1, add 2 each time
printfn "seq: %A" seq1 // seq: seq [1; 3; 5; 7; ...]
- Using for loop
let seq1 = seq { for i in 1 .. 10 -> i }
printfn "seq: %A" seq1
- ofList Views the given list as a sequence
let inputs = [ 1; 2; 5 ]
let seq1 = inputs |> Seq.ofList
printfn "seq: %A" seq1
- ofArray
let inputs = [| 1; 2; 5 |]
let seq1 = inputs |> Seq.ofArray
printfn "seq: %A" seq1
- Seq.initInfinite generate an infinite sequence
let infiniteSeq = Seq.initInfinite (fun i -> i * 2)
printfn "infiniteSeq %A" infiniteSeq
define a start for infinite sequence
let start = 5
let infiniteSeq = Seq.initInfinite (fun i -> i + start)
printfn "infiniteSeq %A" infiniteSeq // infiniteSeq seq [5; 6; 7; 8; ...]
or define a start like this
let infiniteSeq = Seq.initInfinite ((+) 5)
printfn "infiniteSeq %A" infiniteSeq // infiniteSeq seq [5; 6; 7; 8; ...]
Loop Sequence
- for loop
let numbers = seq { 1 .. 10 }
for number in numbers do
printfn "Number: %d" number
- Seq.iter
let numbers = seq { 1 .. 10 }
Seq.iter (fun x -> printfn "Number: %d" x) numbers
Access element
- Seq.item
syntax: Seq.item index source, thrown ArgumentException when the index is negative or the input sequence does not contain enough elements
let numbers = seq { 1 .. 10 }
let thirdElement = Seq.item 2 numbers // Indexing is zero-based
printfn "The third element is %d" thirdElement
- Seq.head && Seq.tail
Seq.head: Returns the first element of the sequence
Seq.tail: Returns a sequence that skips 1 element of the underlying sequence and then yields the remaining elements of the sequence
let numbers = seq { 1 .. 10 }
let firstElement = Seq.head numbers
let restElement = Seq.tail numbers
printfn "The first element is %d" firstElement // The first element is 1
printfn "The rest element is %A" restElement // The rest element is seq [2; 3; 4; 5; ...]
Operate element
- Seq.updateAt
Return a new sequence with the item at a given index set to the new value
syntax: Seq.updateAt index value source
let newSeq = Seq.updateAt 1 9 seq { 0; 1; 2 }
// let newSeq = Seq.updateAt 1 9 (seq { 0; 1; 2 })
printfn "newSeq: %A" newSeq // newSeq: seq [0; 9; 2]
- Seq.filter
Returns a new collection containing only the elements of the collection for which the given predicate returns "true". This is a synonym for Seq.where
syntax: Seq.filter predicateFunc sourceSeq
let numbers = seq { 1 .. 10 }
let evenNumbers = Seq.filter (fun x -> x % 2 = 0) numbers
Seq.iter (fun x -> printfn "Even Number: %d" x) evenNumbers
- Seq.map
Builds a new collection whose elements are the results of applying the given function to each of the elements of the collection
syntax: Seq.filter mappingFunc sourceSeq
let numbers = seq { 1 .. 10 }
let doubleNumbers = Seq.map (fun x -> x * 2) numbers
Seq.iter (fun x -> printfn "doubleNumbers: %d" x) doubleNumbers
- Seq.fold
Applies a function to each element of the collection
syntax: Seq.fold folderFunc state sourceSeq
type Charge =
| In of int
| Out of int
let inputs = [In 1; Out 2; In 3]
let balance = Seq.fold (fun acc charge ->
match charge with
| In i -> acc + i
| Out o -> acc - o) 0 inputs
printfn "balance %A" balance // balance 2
or use pipeline operator to pass state sourceSeq, here is ||> for passing more than one param
type Charge =
| In of int
| Out of int
let inputs = [In 1; Out 2; In 3]
let balance = (0, inputs) ||> Seq.fold (fun acc charge ->
match charge with
| In i -> acc + i
| Out o -> acc - o)
printfn "balance %A" balance // balance 2
Top comments (0)