And*_*ney 5 arrays iteration f#
我有一个单词列表和一个相关的词性标签列表.我想使用每个索引元组作为.NET函数的输入同时迭代两个(匹配索引).这是最好的方式(它有效,但对我来说不自然):
let taggingModel = SeqLabeler.loadModel(lthPath +
"models\penn_00_18_split_dict.model");
let lemmatizer = new Lemmatizer(lthPath + "v_n_a.txt")
let input = "the rain in spain falls on the plain"
let words = Preprocessor.tokenizeSentence( input )
let tags = SeqLabeler.tagSentence( taggingModel, words )
let lemmas = Array.map2 (fun x y -> lemmatizer.lookup(x,y)) words tags
Run Code Online (Sandbox Code Playgroud)
Tom*_*cek 13
你的代码看起来对我很好 - 大部分代码都处理一些加载和初始化,所以你没有太多的东西来简化那部分.或者Array.map2,您可以Seq.zip结合使用Seq.map- 该zip函数将两个序列组合成一个序列,其中包含具有匹配索引的元素对:
let lemmas = Seq.zip words tags
|> Seq.map (fun (x, y) -> lemmatizer.lookup (x, y))
Run Code Online (Sandbox Code Playgroud)
由于lookup函数采用了你作为参数得到的元组,你可以写:
// standard syntax using the pipelining operator
let lemmas = Seq.zip words tags |> Seq.map lemmatizer.lookup
// .. an alternative syntax doing exactly the same thing
let lemmas = (words, tags) ||> Seq.zip |> Seq.map lemmatizer.lookup
Run Code Online (Sandbox Code Playgroud)
||>第二个版本中使用的运算符采用包含两个值的元组,并将它们作为两个参数传递给右侧的函数,这意味着这(a, b) ||> f意味着f a b.该|>运营商需要在左侧只有一个值,所以(a, b) |> f将意味着f (a, b)(这工作,如果函数f预期的元组而不是两个,空格隔开,参数).
如果你需要lemmas在最后成为一个数组,你需要添加Array.ofSeq到处理管道的末尾(所有Seq函数都使用序列,对应于IEnumerable<T>)
还有一种方法是使用序列表达式([| .. |]如果你需要的话,你可以直接构造一个数组):
let lemmas = [| for wt in Seq.zip words tags do // wt is tuple (string * string)
yield lemmatizer.lookup wt |]
Run Code Online (Sandbox Code Playgroud)
是否使用序列表达式 - 这只是个人偏好.在这种情况下,第一个选项似乎更简洁,但对于不熟悉部分函数应用程序(在较短版本中使用Seq.map)的人来说,序列表达式可能更具可读性