F#中原型的Enumerable#pluck?
时间:2020-03-05 18:57:04 来源:igfitidea点击:
在JavaScript中,使用原型库,可以进行以下功能构造:
var words = ["aqueous", "strength", "hated", "sesquicentennial", "area"]; words.pluck('length'); //-> [7, 8, 5, 16, 4]
请注意,此示例代码等效于
words.map( function(word) { return word.length; } );
我想知道在F#中是否可以进行类似的操作:
let words = ["aqueous"; "strength"; "hated";"sesquicentennial"; "area"] //val words: string list List.pluck 'Length' words //int list = [7; 8; 5; 16; 4]
无需写:
List.map (fun (s:string) -> s.Length) words
这对我来说似乎很有用,因为我们不必为每个属性都编写函数来访问它们。
解决方案
回答
原型的pluck
利用了Javascriptobject.method()
中的对象与object [method]
相同。
不幸的是,我们也不能调用String.Length
,因为它不是静态方法。但是,我们可以使用:
#r "FSharp.PowerPack.dll" open Microsoft.FSharp.Compatibility words |> List.map String.length
http://research.microsoft.com/fsharp/manual/FSharp.PowerPack/Microsoft.FSharp.Compatibility.String.html
但是,使用"兼容性"可能会使看代码的人感到困惑。
回答
我在Fmailing列表中看到了请求。希望我能帮上忙。
我们可以使用类型扩展和反射来允许这一点。我们使用pluck函数简单地扩展了通用列表类型。然后我们可以在任何列表上使用pluck()。未知属性将返回一个列表,其中包含错误字符串作为其唯一内容。
type Microsoft.FSharp.Collections.List<'a> with member list.pluck property = try let prop = typeof<'a>.GetProperty property [for elm in list -> prop.GetValue(elm, [| |])] with e-> [box <| "Error: Property '" + property + "'" + " not found on type '" + typeof<'a>.Name + "'"] let a = ["aqueous"; "strength"; "hated"; "sesquicentennial"; "area"] a.pluck "Length" a.pluck "Unknown"
在交互式窗口中产生跟随结果:
> a.pluck "Length" ;; val it : obj list = [7; 8; 5; 16; 4] > a.pluck "Unknown";; val it : obj list = ["Error: Property 'Unknown' not found on type 'String'"]
温暖的问候,
丹尼·阿瑟(DannyAsher)
注意:当使用<pre
>时,尖括号
<'a>
虽然没有显示,但在预览窗口中看起来还不错。反勾号对我没有用。不得不向我们诉诸所有错误的彩色版本。在完全支持FSharp语法之前,我不认为我会在这里再次发表文章。