根据官方定义,F#数组是固定大小的、从0开始、可变的连续数据元素集合,这些元素属于同一类型。一般来说,数组以一维数组和二维数组比较常用。在F#中还有一种列表类型(也是同类型的元素),它和数组的定义比较类似,但是它是不可变的对象,即一旦列表定义好后,我们无法修改特定索引上的元素值,而只能读取。但F#数组却可以进行元素的读取和写入。
//列表leta= [1;2;3] //不可变a.[0] <-1//error/////////////////////////////数组 int[]leta= [|1;2;3|] //可变a.[0] <-1
下面给出一维数组和二维数组的常用用法示例:
moduleArrayDemolettest() =//[|1; 2; 3|]letarr= [|1; 2; 3|] printfn"%A"arrletarr= [|foriin1 .. 10->2*i|] //length=10printfn"length=%d"arr.Length//[|2; 4; 6; 8; 10; 12; 14; 16; 18; 20|]printfn"%A"arr//2printfn"%d"arr.[0] //[|2; 4; 6|]printfn"%A"arr.[0..2] //[|2; 4; 6|]printfn"%A"arr.[..2] //[|6; 8; 10; 12; 14; 16; 18; 20|]printfn"%A"arr.[2..] //修改值arr.[0] <-0//[|0; 4; 6|]printfn"%A"arr.[0..2] letarr=Array.create70.0//[|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]printfn"%A"arrletarr2=Array.subarr02//[|0.0; 0.0|]printfn"%A"arr2letarr2=Array.append [|1; 2; 3|] [|4; 5|] printfn"%A"arr2letarr2=Array.choose(fune->ife%2=0thenSome(e) elseNone) arr2//[|2; 4|]printfn"%A"arr2letarr2=Array.collect (fune-> [|2*e+1|] ) arr2//[|5; 9|]printfn"%A"arr2letarr2=Array.concat [ [|0..3|] ; arr2 ] //[|0; 1; 2; 3; 5; 9|]printfn"%A"arr2letarr2=Array.filter (fune->e%2=1) arr2//[|1; 3; 5; 9|]printfn"%A"arr2letarr2=Array.revarr2//[|9; 5; 3; 1|]printfn"%A"arr2letamap=Array.map2 (fune1e2->e1*e2 ) [|1;2;3|] [|1;2;3|] //[|1; 4; 9|]printfn"%A"amaplets=Array.sumamap//14printfn"%d"slettarr=Array.chunkBySize2 [|1;2;3;4;5;6|] //[|[|1; 2|]; [|3; 4|]; [|5; 6|]|]printfn"%A"tarr////////////////////////////letarr2d=array2D [ [ 1; 0]; [0; 1] ] (* [[1; 0] [0; 1]] *) printfn"%A"arr2dletarr2d=Array2D.init32 (funij->0) (* [[0; 0] [0; 0] [0; 0]] *) printfn"%A"arr2dletarr2d=array2D [ [1;2;3]; [4;5;6] ] //[[4; 5; 6]]printfn"%A"arr2d.[1.. , * ] (*[[2; 3] [5; 6]]*) printfn"%A"arr2d.[* , 1..2 ] //[|2; 5|]printfn"%A"arr2d.[* , 1] //1,2,3Array.iter (fune->printf"%d,"e) [|1;2;3|] //Array.iter (fun e -> printf "%A" e) arr2d //Error//2printfn"%d" (Array2D.length1arr2d) //3printfn"%d" (Array2D.length2arr2d) //1,2,3,4,5,6,Array2D.iter (fune->printf"%d,"e) arr2dprintfn"" (*[0,0]=1 [0,1]=2 [0,2]=3 [1,0]=4 [1,1]=5 [1,2]=6*) Array2D.iteri (funije->printfn"[%d,%d]= %d"ije) arr2d//二维数组letm1=array2D [ [1;2;3]; [4;5;6] ] letm2=array2D [ [7;8;9]; [10;11;12] ] letrlen=Array2D.length1m1letclen=Array2D.length2m1letm3=Array2D.initrlenclen (funij->0) fori=0torlen-1doforj=0toclen-1dom3.[i,j] <-m1.[i,j] +m2.[i,j] (* [[8; 10; 12] [14; 16; 18]] *) printfn"%A"m3
其中的 printfn "%A" arr 可以打印出数组arr的内容。%A即代表数组类型。arr.Length 可以获取一维数组元素的长度。数组的元素可以通过 .[index]来获取,注意前面有一个dot符号,即arr.[0] 可以获取到一维数组arr的第一个元素(下标为0)。另外,还可以给定范围,获取多个元素,即arr.[0..2] 可以获取3个元素,即下标为0,1,2的元素。此外,通过类似 获取元素的用法,还可以省略开始下标或者结束下标,如arr.[..2] 。
数组的创建还可以通过Array.create方法来实现,如let arr = Array.create 7 0.0则创建一个长度为7,初始值为0.0的一维数组,即[|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]。Array.append [| 1; 2; 3|] [| 4; 5|] 方法可以将两个数组进行合并,值为[| 1; 2; 3; 4; 5|] 。Array.concat方法可以将一个二维数组转换成一个一维数组,即Array.concat [ [|0..3|] ; [|5; 9|] ] 生成[|0; 1; 2; 3; 5; 9|] 。
而Array.map2 (fun e1 e2 -> e1*e2 ) [| 1;2;3 |] [| 1;2;3 |] 中的Array.map2可以将两个长度一致的一维数组进行映射,并生成新的数组,返回[|1; 4; 9|]。Array.sum 方法则可以将一维数组中的元素进行求和操作。Array.chunkBySize 2 [| 1;2;3;4;5;6 |]则将一维数组按照2个一组进行拆分,即生成[|[|1; 2|]; [|3; 4|]; [|5; 6|]|] 。
对于二维数组,则可以通过array2D进行定义,如 let arr2d = array2D [ [ 1; 0]; [0; 1] ] 或者通过Array2D.init方法进行初始化,如Array2D.init 3 2 (fun i j -> 0)。对于一个arr2d值为[ [1;2;3]; [4;5;6] ] 的二维数组,arr2d.[1.. , * ] 可以获取到[[4; 5; 6]] 。而下面的示例就可以实现二维数组的和,比如矩阵求和,类似于矩阵求和:
letm1=array2D [ [1;2;3]; [4;5;6] ] letm2=array2D [ [7;8;9]; [10;11;12] ] letrlen=Array2D.length1m1letclen=Array2D.length2m1letm3=Array2D.initrlenclen (funij->0) fori=0torlen-1doforj=0toclen-1dom3.[i,j] <-m1.[i,j] +m2.[i,j] (* [[8; 10; 12] [14; 16; 18]] *) printfn"%A"m3
这里注意,二维数组有两个长度属性,即Array2D.length1代表行数,而Array2D.length2代表列数。