13 4 2 用度量單位格式化資料

2021-08-26 11:17:13 字數 3003 閱讀 6317

13.4.2 用度量單位格式化資料

使用度量的單位

在 f# 中,使用度量單位是很容易的,這就是為什麼我們在這一章介紹它們,作為簡短的題外話。我們可以宣告度量,使用 type 關鍵字,帶專有的屬性。嚴格地說,度量並不是型別,但我們可以將其用作為另一種型別的部分使用。讓我們首先定義兩個簡單的度量,表示小時和公里:

type km

type h

正如你所看到的,我們使用 measure 屬性來指定這個型別是度量。這是乙個專有屬性,f# 編譯器能理解。不一定要我們自己定義單位,我們也可以使用在 fsharp.powerpack.dll 庫中的標準集,但是,現在,我們將使用自己的宣告。現在,我們有了單位 km 和 h,就可以建立表示公里或小時的值。清單 13.15 顯示了如何建立有單位的值,如何寫乙個函式,用它們參與計算。

listing 13.15 writing calculations using units of measure (f#)

> let length = 9.0;;

val length : float= 9.0

> length * length;;

val it : float= 81.0

> let distanceintwohours(speed:float) =

speed * 2.0;;

val distanceintwohours : float-> float

> distanceintwohours(30.0);;

val it : float= 60.0

當我們要指定數字常量的單位時,我們將括尖括號角中的單位加到值的後面。我們首先定義乙個值,表示在長度,以公里計。如果我們用帶單位的值寫計算,f# 自動推斷出結果的單位,所以,我們可以看到,距離乘了兩次,得出以平方公里計的面積。當指定單位時,可以使用常規的表示法,所以,^ 表示乘方,/ 用於除,乘法寫成並列單位。

下乙個示例顯示,我們就可以寫帶引數的函式,其中包括有關單位的資訊。我們的示例函式取速度作引數,返回在兩小時行走的距離。我們想指定引數以公里每小時計,所以,我們新增包含單位的型別注釋。寫成把單位放在尖括號中,與指定型別引數值時的方式相同,比如 list型別。f# 編譯器推斷出返回的型別,就像處理普通的型別一樣。和往常一樣,當我們讀到這個型別時,可以理解函式在執行什麼。這也是有價值的檢查,避免了寫函式時犯低階錯誤:如果我們試圖計算距離,但返回的型別,最後單位是時間,我們便知道錯了。

在我們的世界銀行資料中,我們將使用單位 km^2 表示國家的總面積。所以,到目前為止,一切順利:但是,我們獲得的第二個指標是按百分比提供的。我們如何可以指定百分比的單位?雖然,度量單位主要是用來表示物理單位的,也可以使用它們來表示百分比:

type percent

let coef = 33.0

這段**建立乙個單位,指定數字表示百分比,然後,定義了乙個常數 coef,值是 33%。嚴格地說,以百分比計的值沒有單位,因為,它是乙個係數,但是,它定義成單位是很有用的。為了演示,讓我們嘗試計算 50 公里距離的 33%。由於 coef 表示係數,我們能夠簡單地把這兩個值乘起來:

> 50.0* coef;;

val it : float= 1650.0

這是很明顯的錯誤。我們期望的結果是以公里計,但是,如果你看看推導出的型別,可以看到,結果是以公里乘以新的單位百分比計。因為我們是以互動方式執行的**,還可以看出,數字太大,而度量單位的偉大之處在於,我們可以在型別檢查期間就發現錯誤,而不必實際執行這個程式。所以**出了問題呢?問題是乙個百分比值表示乙個係數乘以 100。要正確寫出計算,需要除以 100% 的值:

> 50.0* coef / 100.0;;

val it : float= 16.5

正如你所看到的,現在好得多了。我們將結果除以 100%,這意味著,在結果中沒有百分比的單位了。f# 自動簡化了單位,知道 km percent/percent 是等同於 km。此示例演示了使用度量單位的重要原因:就像其他型別一樣,它們幫助我們盡可能早的捕獲大量的錯誤。

注意度量單位有很多其他有趣的地方,這個介紹我們沒有涉及到。例如,可以定義派生單位,比如 n (表示力,以牛頓計),這實際上就是kg m/s^2。在函式或型別中使用單位作為泛型型別引數,也是可能的。有關度量單位的詳細資訊,請參閱 f# 聯機文件,和架構師 andrew kennedy 關於該功能的部落格(

格式化世界銀行的資料

listing 13.16 converting raw data into a typed data structure (f#)

let areas =

seq.concat(data.[0..2])

|> readvalues (fun a -> float(a) * 1.0)

|> map.ofseq

let forests =

seq.concat(data.[3..5])

|> readvalues (fun a -> float(a) * 1.0)

|> map.ofseq

第乙個處理流運算把所有頁中的資料連線第乙個指標,將每個值從字串轉換以平方公里計的數字,然後,從資料生成乙個對映。第二個命令,處理森林覆蓋面積是類似的。

資料處理的主要部分是使用流運算寫的。它使用一種我們還沒未介紹的新功能,從資料集中取前三個元素。這被稱為切片(slicing),語法 data.[0..2]生成乙個序列,包含索引從 0 到 2 的陣列項。用 seq.concat 連線返回的序列,這樣,就能得到乙個包含所有年份資料的序列。流運算的下一步是讀這些值,並將其轉換為適當的帶度量單位的型別。這原來是最簡單的部分,就是乙個簡單的 lambda 表示式!要注意的是,世界銀行使用點作為分隔符,所以,數字就如 1.0。內建的 float 函式始終使用固定區域設定,因此,在任何系統上,它都能正確解析字串。

我們使用 map.ofseq 函式,從資料生成 f# 對映型別。這個函式取包含元組的序列作為引數值,並以第乙個元素作為鍵值,第二個元素作為值。在清單 13.16 中,鍵值的型別為 int * string,其中包含年和區域名。在第一種情況中的值的型別為 float,第二種情況為 float。我們已經把資料轉換成對映,因此,可以輕鬆地檢視不同年份和區域的各項指標。

大資料常用度量單位

建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...

Eval 中資料格式化或格式化資料

eval schoolend dbnull.value convert.todatetime eval schoolend tostring yyyy mm dd 不帶null的 datetime eval se start date tostring yyyy mm dd eval beginda...

JS格式化資料

前端經常遇到要處理後台返回的json資料,並且希望能夠按照一定格式進行展示,便於讀者檢視.此方法便可以進行操作 let txt fomatjson txt,false return try catch e console.log 資料來源語法錯誤,格式化失敗 錯誤資訊 e.description,e...