List 在Scala中基于元素值拆分列表
是否有基于元素值将列表拆分为子列表的内置函数(或简单实现) 例如,如果列表为:List 在Scala中基于元素值拆分列表,list,scala,split,List,Scala,Split,是否有基于元素值将列表拆分为子列表的内置函数(或简单实现) 例如,如果列表为: val myList = List("a","b","c","","e","d","a","","d","a") 并且每当元素“”出现时,我都希望将其拆分(在我的情况下,我也会删除此类元素,但通常可以将其与上一个子列表
val myList = List("a","b","c","","e","d","a","","d","a")
并且每当元素“”出现时,我都希望将其拆分(在我的情况下,我也会删除此类元素,但通常可以将其与上一个子列表或下一个子列表分组),以获得输出:
List(List("a","b","c"),List("e","d","a"),List("d","a"))
我一直在stack和google中寻找答案,但令人惊讶的是,我没能找到答案
如果有帮助的话,这是在Mathematica中我可以解决的问题:
SplitBy[myList, # != "" &]
(或者几乎等同于使用
Split
)AFAIK,这样的函数在stdlib上不存在,但是您可以非常轻松地创建自己的函数
defsplitby[A](list:list[A])(p:A=>Boolean):list[list[A]={
@注释.tailrec
def循环(剩余:列表[A]、currentList:List[A]、acc:List[List[A]]):List[List[A]]=
剩余比赛{
案例a::as=>
if(p(a))循环(剩余=as,currentList=List.empty,currentList.reverse::acc)
else循环(剩余=as,a::currentList,acc)
案例无=>
(currentList.reverse::acc).反向
}
循环(剩余=列表,当前列表=列表.empty,acc=列表.empty)
}
您可以这样使用:
val myList=List(“a”、“b”、“c”、“e”、“d”、“a”、“d”、“a”)
val result=splitBy(myList)(==“”)
//val结果:List[List[String]=List(List(a,b,c),List(e,d,a),List(d,a))
请注意,此函数可用于的
流
数据类型。(对于您的用例来说,这可能是一种过分的做法,但值得一提)
stream.groupAdjacentBy(p).collect{
大小写(false,chunk)=>chunk
}
您可以看到代码正在运行另一个选项是使用foldLeft:
myList.foldRight(List(List[String]()))((s, l) => {
if (s.isEmpty) {
List() :: l
} else {
(s :: l.head) :: l.tail
}
})
代码运行于。使用可变集合应该更有效,而不是此代码甚至不是通用代码,无法用于不同的谓词(但这可能很容易更改)。然而,这是非常低效的;而且,我个人觉得很难理解。@LuisMiguelMejíaSuárez,同样可以通过
foldRight
实现,这应该是有效的,因为我不会在列表的末尾添加元素。提取条件相当容易,如果需要的话。@TomerShetah fair,它之所以有效,是因为foldRight
的stdlib实现“欺骗”,但这是Scala而不是Haskell。