使用scala中的数学逻辑删除列表中的特定元素

时间:2016-10-31 23:10:29

标签: scala list math logic

如果我有这个清单:

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

如何通过消除List第一个头上的非重复数字来更新列表?所以结果应该是:

val aRes = List(1,1,1), List(3,3), List(7,7,7)

List(2,3,3,2,6)也应该删除,因为我们不会在列表的头部有3个。我对结果的期望是:

val aRes = aList(1) map {case List(i) => List(aList.groupBy(_(1))}

但这似乎对这种逻辑无效。

除此之外,我还需要将这些结果值转换为另一个列表成员:

val aScore = List(
      /*score for 1*/ List(0, 0, 1500, 2500, 5000),
      /*score for 2*/ List(0, 0, 500, 1000, 2000),
      /*score for 3*/ List(0, 50, 100, 200, 500),
      /*score for 4*/ List(0, 10, 50, 100, 150),
      /*score for 5*/ List(0, 10, 50, 100, 150),
      /*score for 6*/ List(0, 10, 50, 100, 150),
      /*score for 7*/ List(0, 10, 50, 100, 150)
    )

val score = ???

因此,从上面的aList结果中,得分必须为1500+50+50 = 1600 1*3=>15003*2=>507*3=>50

3 个答案:

答案 0 :(得分:4)

如果有重复项,您想要返回一些内容,如果没有,则返回任何内容,因此创建一个返回Option的函数:

def f(xs: List[Int]) = xs match {
  case x0 :: x1 :: _ if x0 == x1 => Some(xs.takeWhile(_ == x0))
  case _ => None
}

然后flatMap你的清单,以摆脱选择位:

aList.flatMap(f)

第二部分:

def getScore(xs: List[Int]) = aScore(xs.head - 1)(xs.size - 1)

所以只需对元素进行映射和求和。总计:

aList.flatMap(f).map(getScore).sum   
// result = 1600

答案 1 :(得分:3)

object parseData {
  val inputList = List(List(1,1,1,3,4),List(3,3,5,6,7),List(7,7,7,6,7),List(2,3,3,2,6))
  val aScore = List(
    /*score for 1*/ List(0, 0, 1500, 2500, 5000),
    /*score for 2*/ List(0, 0, 500, 1000, 2000),
    /*score for 3*/ List(0, 50, 100, 200, 500),
    /*score for 4*/ List(0, 10, 50, 100, 150),
    /*score for 5*/ List(0, 10, 50, 100, 150),
    /*score for 6*/ List(0, 10, 50, 100, 150),
    /*score for 7*/ List(0, 10, 50, 100, 150)
  )

  def isDuplicated(aList: List[Int]): Boolean = aList.head == aList.tail.head

  def getRidOfNonDuplicates(aList: List[Int]): List[Int] = {
    val opList = ListBuffer(aList.head)
    def loop(aList: List[Int], opList: ListBuffer[Int]): Unit = {
      if (aList.tail == Nil) return
      if (aList.head == aList.tail.head) opList += aList.tail.head
      loop(aList.tail, opList)
    }
    loop(aList, opList)
    opList.toList
  }

  def printaScoreValue(aList: List[Int]): Unit = println(aScore(aList.head - 1)(aList.length - 1))

  val outputList = inputList.filter(isDuplicated(_))
  val opList = ListBuffer.empty[List[Int]]
  for (aList <- outputList)
    opList += getRidOfNonDuplicates(aList)
  opList.foreach(printaScoreValue(_))
}

给出

1500
50
50

答案 2 :(得分:1)

我的第一次刺伤是:

scala> val ls =  List(List(1,1,1,3,4),List(3,3,5,6,7),List(7,7,7,6,7),List(2,3,3,2,6))
ls: List[List[Int]] = List(List(1, 1, 1, 3, 4), List(3, 3, 5, 6, 7), List(7, 7, 7, 6, 7), List(2, 3, 3, 2, 6))

scala> ls map { 
  _ groupBy identity filter { case (i, is) => is.length > 1 } flatMap { _._2 } 
}
res2: List[List[Int]] = List(List(1, 1, 1), List(3, 3), List(7, 7, 7, 7), List(2, 2, 3, 3))

但正如你所看到的,它不是你想要的。我认为下一个钉住它:

scala> ls map { l => 
         val (h,t) = (l.head, l.tail) 
         h :: t.takeWhile( _ == h ) 
       } filter { _.length > 1 }
res7: List[List[Int]] = List(List(1, 1, 1), List(3, 3), List(7, 7, 7))

但是请注意,如果List.empty是外部列表的元素,它就无法工作。