【F#2.0系列】使用F#的List

使用F#List

创建一个list

语法

描述

示例

[]

list

[]

expr :: expr

将一个项加入一个list

1 :: [2; 3]

[expr; ...; expr]

列举项创建list

[1; 2; 3]

[expr .. expr]

连续的数字

[1 .. 99]

[ for x in list ... ]

通过运算生成list(类似于Linq里的select

[ for x in 1..99 -> x * x ]

expr @ expr

合并两个list

[1; 2] @ [3]

 

操作示例:

let oddPrimes = [3; 5; 7; 11]

let morePrimes = [13; 17]

let primes = 2 :: (oddPrimes @ morePrimes)

 

val primes : int list = [2; 3; 5; 7; 11; 13; 17]

 

list同样是不可变的(immutable):操作符“::”并未真正改变原list本身,相反的,它创建了一个新的list。示例:

> let people = [ "Adam"; "Dominic"; "James" ];;

val people : string list

 

> people;;

val it : string list = [ "Adam"; "Dominic"; "James" ]

 

> "Chris" :: people;;

val it : string list = [ "Chris"; "Adam"; "Dominic"; "James" ]

 

> people;;

val it : string list = [ "Adam"; "Dominic"; "James" ]

 

如你所见,people并未被改变。在内存中,F#list表示为关联的list;每个F#list的值(value)包含了自身的值以及指向下一个列表的指针。也就是说当你使用“::”来创建一个新的list的时候,新list的尾部就包含了一个指向老list的指针。

在我看来,通过不可变性与指针的结合,提高了list的内存利用效率。

我们再看一个分解(decompose)list的例子:

let oddPrimes = [3; 5; 7; 11]

let printFirst primes =

    match primes with

    | h :: t -> printfn "The first prime in the list is %d" h

    | [] -> printfn "No primes found in the list"

> printFirst oddPrimes;;

The first prime in the list is 3

val it : unit = ()

 

程序通过h::t来分解listh代表list的第一个元素,t代表其后续。[]代表空listmatch是匹配开始关键字,primes是匹配源,通过|表示各种匹配条件。感觉类似于switch case

F#包含了一个List模块。其提供了一些功能:

方法

类型

描述

List.length

'T list -> int

返回list长度

List.head

'T list -> 'T

返回非空list的第一个元素

List.tail

'T list -> 'T list

返回非空list中除了第一个元素外的其他所有元素

List.init

int -> (int -> 'T) -> 'T list

通过一个可以通过索引生成值的函数来构造一个定长list

List.append

'T list -> 'T list -> 'T list

返回一个合并后的list

List.filter

('T -> bool) -> 'T list -> 'T list

返回一个新的过滤后的列表。

List.map

('T -> 'U) -> 'T list -> 'U list

将一个list通过一个转换函数转换为另一个list

List.iter

('T -> unit) -> 'T list -> unit

list中的每个项执行一次指定的函数

List.unzip

('T * 'U) list -> 'T list * 'U list

zip操作的反向操作

List.zip

'T list -> 'U list -> ('T * 'U) list

将两个拥有相同长度的list合并成一个新的list,相同index的项会组合成元组(tuple),并作为新list中的项。

List.toArray

'T list -> 'T[]

从一个list生成一个array

List.ofArray

'T[] -> 'T list

从一个array生成一个list

上面的说明还都是比较抽象的,示例如下:

> List.head [5; 4; 3];;

val it : int = 5

 

> List.tail [5; 4; 3];;

val it : int list = [ 4; 3 ]

 

> List.map (fun x -> x*x) [1; 2; 3];;

val it : int list = [ 1; 4; 9 ]

 

> List.filter (fun x -> x % 3 = 0) [2; 3; 5; 7; 9];;

val it : int list = [ 3; 9 ]

从上例可得知,我们可以使用fun关键字来表示匿名函数。

一些通用的不可变数据结构

数据类型大概可以分为可变(mutable)的和不可变(immutable)的两种。不可变类型有时会被称为持久(persistent)或函数体(functional)F#中常用的不可变类型:

·         元组(Tuple)和选项(option):他们都是不可变类型并且是F#的基本(basic workhorse)

·         不可变链表’T list:非常适合从左至右的便利。但不适合随机访问。随机访问的时间复杂度为O(n)nlist的长度。全名为:Microsoft.FSharp.Collections.List<’T>

·         基于平衡树(balanced tree)的不可变set类型:非常适合添加,访问和合并,O(log(n))的访问时间复杂度。因为此类型是不可变的,内部的节点可以在不同的sets之间共享。

·         基于平衡树(balanced tree)不可变的map类型:简单的说就是不可变的字典类型(dictionary)。也同样拥有O(log(n))的访问时间复杂度。

 

目录传送门    

转载于:https://www.cnblogs.com/pandora/archive/2010/08/30/FSharp_UsingList.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值