在满足谓词(Scala)的每个元素处拆分列表 [英] Split up a list at each element satisfying a predicate (Scala)

查看:170
本文介绍了在满足谓词(Scala)的每个元素处拆分列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在文本文件中,我有以下形式的数据:

  1)
text
text
2)
更多文本
3)
更多文本
更多甚至文本
更多文本
...

我使用以下内容将其读为字符串列表:

  val input = io.Source.fromFile(filename.txt)。getLines()。toList 

我想将列表拆分为以 1开头的子列表 2)等。



我想出了:

  val subLists = 
input.foldRight(List(List [String]())){
(x,acc)=>
if(x.matches([0-9] + \)))List()::(x :: acc.head):: acc.tail
else (x :: acc.head):: acc.tail
} .tail

这个更容易实现?如果有一个内置的方法来分割每个满足谓词(hint,hint,库设计器:)的元素的集合,那么什么是真正好的。

解决方案

foldRight 有一个复杂的参数通常表明你可能使用递归编写,自己的方法,而你在它。这是我想出的。首先,让我们将
泛化为一个通用方法:groupPrefix:

  / **返回最小列表xss 
* - xss.flatten == xs
* - xss中没有子列表在其尾部包含匹配p的元素
* /
def groupPrefix [T](xs:List [T])(p:T => Boolean):List [List [T]] = xs match {
case List() List()
case x :: xs1 =>
val(ys,zs)= xs1 span(!p(_))
(x :: ys):: groupPrefix(zs)(p)
} code>



现在,您只需调用

即可获得结果。

  groupPrefix(input)(_ matches\d + \))


In a text file I have data in the form:

1)
text
text
2)
more text
3)
even more text
more even text
even more text
...

I read it as a list of Strings using the following:

val input = io.Source.fromFile("filename.txt").getLines().toList

I want to break the list down into sub-lists starting with 1), 2) etc.

I've come up with:

val subLists =
  input.foldRight( List(List[String]()) ) {
    (x, acc) =>
      if (x.matches("""[0-9]+\)""")) List() :: (x :: acc.head) :: acc.tail
      else (x :: acc.head) :: acc.tail
  }.tail

Can this be achieved more simply? What would be really nice would be if there were a built-in method to split a collection on every element that satisfies a predicate (hint, hint, library designers :)).

解决方案

foldRight with a complicated argument is usually an indication that you might as well write this using recursion, and factor it out to its own method, while you are at it. Here's what I came up with. First, let's generalize to a generic method, groupPrefix:

 /** Returns shortest possible list of lists xss such that
  *   - xss.flatten == xs
  *   - No sublist in xss contains an element matching p in its tail
  */
 def groupPrefix[T](xs: List[T])(p: T => Boolean): List[List[T]] = xs match {
   case List() => List()
   case x :: xs1 => 
     val (ys, zs) = xs1 span (!p(_))
     (x :: ys) :: groupPrefix(zs)(p)  
 }

Now you get the result simply by calling

 groupPrefix(input)(_ matches """\d+\)""")

这篇关于在满足谓词(Scala)的每个元素处拆分列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆