我正在尝试学习
Scala并尝试编写一个序列理解,从序列中提取unigrams,bigrams和trigrams.例如,[1,2,3,4]应转换为(不是Scala语法)
[1; _,1; _,_,1; 2; 1,2; _,1,2; 3; 2,3; 1,3; 4; 3,4; 2,4]
在Scala 2.8中,我尝试了以下方法:
def trigrams(tokens : Seq[T]) = { var t1 : Option[T] = None var t2 : Option[T] = None for (t3 <- tokens) { yield t3 yield (t2,t3) yield (t1,t2,Some(t3)) t1 = t2 t2 = t3 } }
但这不会编译为,apparently,在for-comprehension中只允许一个yield(也没有块语句).有没有其他优雅的方法来获得相同的行为,只有一次传递数据?
解决方法
for循环中不能有多个yield,因为for循环是map(或flatMap)操作的语法糖:
for (i <- collection) yield( func(i) )
翻译成
collection map {i => func(i)}
没有收益
for (i <- collection) func(i)
翻译成
collection foreach {i => func(i)}
因此,for循环的整个主体变为单个闭包,yield关键字的存在确定对集合调用的函数是map还是foreach(或flatMap).由于此翻译,禁止以下内容:
>在yield旁边使用命令式语句来确定将产生什么.
>使用多个收益率
(更不用说你提出的verison会返回一个List [Any],因为元组和1-gram都是不同的类型.你可能想要得到一个List [List [Int]])
请尝试以下方法(将n-gram按其出现的顺序排列):
val basis = List(1,4) val slidingIterators = 1 to 4 map (basis sliding _) for {onegram <- basis ngram <- slidingIterators if ngram.hasNext} yield (ngram.next)
要么
val basis = List(1,4) val slidingIterators = 1 to 4 map (basis sliding _) val first=slidingIterators head val buf=new ListBuffer[List[Int]] while (first.hasNext) for (i <- slidingIterators) if (i.hasNext) buf += i.next
如果您希望n-gram为长度顺序,请尝试:
val basis = List(1,4) 1 to 4 flatMap { basis sliding _ toList }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。