在F#中将对象映射/转换为另一个

时间:2013-12-05 09:19:02

标签: linq f#

我是F#的初学者并玩弄它,直到我遇到这个问题。我搜索它但找不到任何东西。我想将一个对象变异为另一个。我有Geolocation对象有很多属性,其中两个是纬度和经度。我想创建一个新的动态对象但是使用管道或选择运算符,只有属性的子集

let customLocation = OtherPlace.Geolocation ....

我该怎么做?

2 个答案:

答案 0 :(得分:4)

假设你有一个OtherPlace.Geolocation数组

geoLocations :  OtherPlace.Geolocation array

然后,您可以根据需要:

  • 使用元组(这只是记录的特例)

 //of type (double * double) array
let g = geoLocations |> Array.map (fun x -> x.Latitude, x.Longitude)  
  • 创建记录类型(nb:元组只是具有位置名称的记录)

type Position = {Latitude : double; Longitude : double}

//of type Position array
let g = geoLocations |> Array.map (fun x -> x.Latitude, x.Longitude) 

对于小的本地需求,元组更适合但可能变得笨拙。

记录允许您更好地构建程序


联盟案例应该用于区分不同的事物,这仍然代表了一些共同的概念。 例如,您可以在不同的系统中表达职位

type GeoPosition = | LaTLong of double * double
                   | WGS84 of double * double
                   | ...

//of type GeoPosition array
let g = geoLocations |> Array.map (fun x -> LatLong (x.Latitude, x.Longitude))  

PS:如果你使用F#3.1你有一个额外的糖用于命名联合类型字段,如图所示here

答案 1 :(得分:4)

解决此类问题的最佳方法是使用单个案例创建一个有区别的联合。您可以使用直型别名,但是会丢失少量的类型安全性。要定义类型使用:

type Loc = |LL of float * float

然后您可以使用以下内容创建实例:

Something |> fun t -> LL(t.Latitude,t.Longitude)

或更简单的版本:

LL(something.Latitude,something.Longitude)