在scala列表中计数模式

时间:2014-02-14 22:22:50

标签: scala

我的列表如下所示:List(Person,Invite,Invite,Person,Invite,Person...)。我正在尝试根据inviteCountRequired进行匹配,这意味着列表中Invite对象后面的Person个对象是可变的。这样做的最佳方式是什么?到目前为止,我的匹配代码如下所示:

aList match { 
     case List(Person(_,_,_),Invitee(_,_,_),_*) => ...
     case _ => ...
}

第一个堆叠问题,请放轻松我。

3 个答案:

答案 0 :(得分:0)

val aList = List(Person(1), Invite(2), Invite(3), Person(2), Invite(4), Person(3), Invite(6), Invite(7))

然后索引列表中的每个位置并选择Person个实例,

val persons = (aList zip Stream.from(0)).filter {_._1.isInstanceOf[Person]}

List((Person(1),0), (Person(2),3), (Person(3),5))。然后定义子列表,其中下限对应于Person实例,

val intervals = persons.map{_._2}.sliding(2,1).toArray
res31: Array[List[Int]] = Array(List(0, 3), List(3, 5))

构建子列表,

val latest = aList.drop(intervals.last.last)  // last Person and Invitees not paired
val associations = intervals.map { case List(pa,pb,_*) => b.slice(pa,pb) } ++ latest

因此结果看起来像

Array(List(Person(1), Invite(2), Invite(3)), List(Person(2), Invite(4)), List(Person(3), Invite(6), Invite(7)))

现在,

associations.map { a => 
  val person = a.take(1)
  val invitees = a.drop(1) 
  // ...
}

这种方法可能被视为可变大小的滑动。

答案 1 :(得分:0)

感谢您的提示。我最终创建了另一个案例类:

case class BallotInvites(person:Person,invites:List[Any])

然后,我从原始列表填充它:

def constructBallotList(ballots:List[Any]):List[BallotInvites] ={

  ballots.zipWithIndex.collect {
      case (iv:Ballot,i) =>{
                        BallotInvites(iv,
                          ballots.distinct.takeRight(ballots.distinct.length-(i+1)).takeWhile({
                            case y:Invitee => true
                            case y:Person =>true
                            case y:Ballot => false})
                          )}

  }}
val l = Ballot.constructBallotList(ballots) 

然后根据inviteCountRequired计算,我做了以下事情:

val count = l.count(b=>if ((b.invites.count(x => x.isInstanceOf[Person]) / contest.inviteCountRequired)>0) true else false )

答案 2 :(得分:0)

我不确定我是否了解域名,但您只需要迭代一次即可构建人员+邀请元组列表。

sealed trait PorI
case class P(i: Int) extends PorI
case class I(i: Int) extends PorI

val l: List[PorI] = List(P(1), I(1), I(1), P(2), I(2), P(3), P(4), I(4))

val res = l.foldLeft(List.empty[(P, List[I])])({ case (res, t) =>
  t match {
    case p @ P(_) => (p, List.empty[I]) :: res
    case i @ I(_) => {
      val head :: tail = res
      (head._1, i :: head._2) :: tail
    }
  }
})

res // List((P(4),List(I(4))), (P(3),List()), (P(2),List(I(2))), (P(1),List(I(1), I(1))))