List Scala访问列表对象并计算周期数

List Scala访问列表对象并计算周期数,list,scala,apache-spark,List,Scala,Apache Spark,Scala访问列表对象并计算周期数 我有一张物品清单 case class ItemDesc(a: Int, b: Int, c: Int, d: Int,e: Int, f: Int, g: Int desc: String) val example = List(ItemDesc(6164,6165,6166,-6195,-6175,-6186,-6195, The values are correct), ItemDesc(14879,-14879,14879,-14894, 1487

Scala访问列表对象并计算周期数

我有一张物品清单

case class ItemDesc(a: Int, b: Int, c: Int, d: Int,e: Int, f: Int, g: Int desc: String)


val example = List(ItemDesc(6164,6165,6166,-6195,-6175,-6186,-6195, The values are correct), ItemDesc(14879,-14879,14879,-14894, 14879,14879,14894, The values are ok), ItemDesc(19682,-19690,-19682,19694,19690,19682,19694,The values are good),ItemDesc(5164,-5165,-5166,-6195,5165,5166,6195,The values are correct),ItemDesc(5879,5879,5879,5894,5879,5879,5879,The values are ok))
从“示例”列表中,我想访问对象“ItemDesc”。并获得周期数。它从负值变为正值并保持正值>=2秒的次数

如果>=2秒,则为循环

示例1:(616461656166,-6195,-6175,-6186,-6195,好)

循环次数为2次

原因:当我们从列表的第一个元素移动到第三个元素时,我们有两个间隔,这意味着2秒。间隔>=2。所以这是一个循环。当我们移动到列表的第三个元素到第四个元素时,它是一个负值。所以我们从第四元素开始计数,然后移到第七元素,所有元素都有相同的负号。我们有3次间隔,也就是3秒。间隔>=2。所以这是一个循环。当一个数字从正变为负时,我们开始从零开始计算新的间隔,反之亦然

示例2:(14879,-1487914879,-14894,148791487914894,更好)

循环次数为1

原因:当我们从列表的第一个元素移动到第二个元素时,符号变为负数。所以我们从零开始计算间隔。从元素2到元素3,符号变为负数。所以间隔计数器是零。从元素3到元素4,符号变为负数。间隔计数器为零。从5号到7号,所有值都有相同的符号,我们有2个间隔,即2秒。间隔>=2。所以这是一个循环

例3:(5164,-5165,-5166,-6195516551666195,好)

循环次数为2次

下面我写的代码没有给出我正在寻找的循环数。感谢您的帮助

object findCycles {
def main(args: Array[String]) {

var numberOfPositiveCycles = 0
var numberOfNegativeCycles = 0
var numberOfCycles = 0

case class itemDesc(a: Int, b: Int, c: Int, d: Int, reason: String)

val example = List(ItemDesc(6164,6165,6166,-6195,-6175,-6186,-6195, The values are correct), ItemDesc(14879,-14879,14879,-14894, 14879,14879,14894, The values are ok), ItemDesc(19682,-19690,-19682,19694,19690,19682,19694,The values are good),ItemDesc(5164,-5165,-5166,-6195,5165,5166,6195,The values are correct),ItemDesc(5879,5879,5879,5894,5879,5879,5879,The values are ok))    

val data2 = example.map(x => getInteger(x)).filter(_ != "unknown").map(_.toString.toInt)
//println(data2)

     var nCycle = findNCycle(data2)
     println(nCycle)
   }

    def getInteger(obj: Any) = obj match {
    case n: Int => obj
    case _     => "unknown"
    }

   def findNCycle(obj: List[Int]) : Int = {      

    def NegativeCycles(fit: itemDesc): Int = {
    if (fit.a < 0 && fit.b < 0 && fit.c < 0) || if( fit.b < 0 && fit.c < 0 && fit.d < 0)
    {
      numberOfNegativeCycles += 1
    }
    }
    //println("negative cycle="+cycles)
    def PositiveCycles(fit: itemDesc): Int = {
      if (fit.a > 0 && fit.b > 0 && fit.c > 0) || if( fit.b > 0 && fit.c > 0 && fit.d > 0)
      {
        numberOfPositiveCycles += 1
      }
    }
    //println("positive cycle="+cycles)

    numberOfCycles = numberOfPositiveCycles + numberOfNegativeCycles
    return numberOfCycles 

  }
对象查找周期{
def main(参数:数组[字符串]){
var numberOfPositiveCycles=0
var numberOfNegativeCycles=0
var numberOfCycles=0
案例类itemDesc(a:Int,b:Int,c:Int,d:Int,reason:String)
val example=List(ItemDesc(616461656166,-6195,-6175,-6186,-6195,值正确)、ItemDesc(14879,-1487914879,-14894,148791487914894,值正常)、ItemDesc(19682,-19690,-1968219694196901968219694,值正确)、ItemDesc(5164,-5165,-5166,-61955165516695,值正确)、ItemDesc(587958795879587994587958795879,数值正常))
val data2=example.map(x=>getInteger(x)).filter(!=“未知”).map(33;.toString.toInt)
//println(数据2)
var nCycle=findNCycle(数据2)
println(nCycle)
}
def getInteger(对象:任意)=对象匹配{
案例n:Int=>obj
案例u=>“未知”
}
def findNCycle(obj:List[Int]):Int={
def负循环(拟合:itemDesc):Int={
if(fit.a<0&&fit.b<0&&fit.c<0)| if(fit.b<0&&fit.c<0&&fit.d<0)
{
负周期数+=1
}
}
//println(“负循环=+循环)
def正循环(拟合:itemDesc):Int={
if(fit.a>0&&fit.b>0&&fit.c>0)| if(fit.b>0&&fit.c>0&&fit.d>0)
{
正循环数+=1
}
}
//println(“正周期=“+周期”)
numberOfCycles=numberOfPositiveCycles+numberOfNegativeCycles
返回循环数
}
}
关于逻辑的参考,你可以参考-

好的,这很粗糙,但我认为它符合你的要求。我相信有一种更优雅的方法来实现拆分方法

我没有使用您的ItemDesc,因为它更简单,可以根据您给出的示例演示问题

object CountCycles extends App {

  // No. of cycles is 1.
  val example1 = List(1, 2, 3, 4, 5, 6, -15, -66)

  // No. of cycles is 3.
  val example2 = List(11, 22, 33, -25, -36, -43, 20, 25, 28)

  // No. of cycles is 8
  val example3 = List(1, 4, 82, 5, 6, -2, -12, -22, -32, 100, 102, 100, 102, 0, 0, -2, -12, -22, -32, 4, 82, 5, 6, -6, 8, -6, -6, 8, 8, -5, -6, -7, 9, 8, 6, -5, -6, -7)

  def differentSign(x: Int, y: Int): Boolean =
    (x < 0) != ( y < 0)

  // return a list of sections
  def split(l: List[Int]): List[List[Int]] =
    l match {
      case Nil ⇒ Nil
      case h :: _ ⇒
        val transition: Int = l.indexWhere(differentSign(h, _))
        if (transition < 0) List(l)
        else {
          val (head, tail) = l.splitAt(transition)
          head :: split(tail)
        }
    }

  def count(l: List[Int]): Int = {
    val pos: List[List[Int]] = split(l)
    // count is the number of sections of length > 2
    pos.count(_.length > 2)
  }

  println(count(example1)) // 1
  println(count(example2)) // 3
  println(count(example3)) // 8
}
objectcountcycles扩展应用程序{
//循环次数为1。
val example1=列表(1,2,3,4,5,6,-15,-66)
//循环次数为3次。
val example2=列表(11,22,33,-25,-36,-43,20,25,28)
//循环次数为8次
val example3=列表(1,4,82,5,6,2,12,22,32,100,102,100,102,0,0,2,12,22,32,4,82,5,6,6,8,8,5,6,7,9,8,6,5,6,6,7)
def differentSign(x:Int,y:Int):布尔值=
(x<0)!=(y<0)
//返回节的列表
def拆分(l:List[Int]):List[List[Int]]=
我匹配{
无案例⇒ 无
案例h::⇒
val转换:Int=l.indexWhere(差分符号(h,u2;))
如果(转换<0)列表(l)
否则{
val(头部、尾部)=l.splitAt(过渡)
头部:分裂(尾部)
}
}
def计数(l:列表[Int]):Int={
val pos:List[List[Int]=split(l)
//count是长度>2的节数
位置计数(长度>2)
}
println(计数(示例1))//1
println(计数(示例2))//3
println(计数(示例3))//8
}

好的,这很粗糙,但我认为它符合您的要求。我相信有一种更优雅的方法来实现拆分方法

我没有使用您的ItemDesc,因为它更简单,可以根据您给出的示例演示问题

object CountCycles extends App {

  // No. of cycles is 1.
  val example1 = List(1, 2, 3, 4, 5, 6, -15, -66)

  // No. of cycles is 3.
  val example2 = List(11, 22, 33, -25, -36, -43, 20, 25, 28)

  // No. of cycles is 8
  val example3 = List(1, 4, 82, 5, 6, -2, -12, -22, -32, 100, 102, 100, 102, 0, 0, -2, -12, -22, -32, 4, 82, 5, 6, -6, 8, -6, -6, 8, 8, -5, -6, -7, 9, 8, 6, -5, -6, -7)

  def differentSign(x: Int, y: Int): Boolean =
    (x < 0) != ( y < 0)

  // return a list of sections
  def split(l: List[Int]): List[List[Int]] =
    l match {
      case Nil ⇒ Nil
      case h :: _ ⇒
        val transition: Int = l.indexWhere(differentSign(h, _))
        if (transition < 0) List(l)
        else {
          val (head, tail) = l.splitAt(transition)
          head :: split(tail)
        }
    }

  def count(l: List[Int]): Int = {
    val pos: List[List[Int]] = split(l)
    // count is the number of sections of length > 2
    pos.count(_.length > 2)
  }

  println(count(example1)) // 1
  println(count(example2)) // 3
  println(count(example3)) // 8
}
objectcountcycles扩展应用程序{
//循环次数为1。
val example1=列表(1,2,3,4,5,6,-15,-66)
//循环次数为3次。
val example2=列表(11,22,33,-25,-36,-43,20,25,28)
//循环次数为8次
val example3=列表(1,4,82,5,6,2,12,22,32,100,102,100,102,0,0,2,12,22,32,4,82,5,6,6,8,8,5,6,7,9,8,6,5,6,6,7)
def differentSign(x:Int,y:Int):布尔值=
(x<0)!=(y<0)
//返回节的列表
def拆分(l:List[Int]):List[List[Int]]=
我匹配{
无案例⇒ 无
案例h::⇒
val转换:Int=l.indexWhere(差分符号(h,u2;))
如果(转换<0)列表(l)
否则{
val(头部、尾部)=l.splitAt(过渡)
头部:分裂(尾部)
}
}
def计数(l:列表[Int]):Int={
val pos:List[List[Int]=split(l)
//count是长度>2的节数
位置计数(长度>2)
}
println(计数(示例1))//1
println(计数(示例2))//3
println(计数(示例3))//8
}

这应该是一个有效的解决方案,适用于您在列表中有7项的情况
Item at index 0 has 2 cycles
Item at index 1 has 1 cycles
Item at index 2 has 1 cycles
Item at index 3 has 2 cycles
Item at index 4 has 1 cycles
case class ItemDesc(a: Int, b: Int, c: Int, d: Int, reason: String) {
    lazy val getAsList = List(a,b,c,d)
  }

ItemDesc(1,2,3,4,"reason").getAsList
case class ItemDescAlt(reason:String, elements: Int*)

ItemDescAlt("reason", 5164,-5165,-5166,-6195,5165,5166,6195)
def getCycles(list: Seq[Int]): Int = {
    def headPositive(list: Seq[Int]): Boolean = {
      list.headOption.forall(_ >= 0)
    }
    val result = list.foldLeft((0, 0, !headPositive(list))) { //we start with a symbol diferent to the firs one
      case ((numberOfCycles, cycleLength, lastWasPositive), number) => { //for each element...
        val numberSign = number >= 0
        val actualCycleLength = if (numberSign == lastWasPositive) { //see if the actual simbol is equal to the last one
          cycleLength + 1 //in that case the length is increased
        } else {
          0 //in the other reset it
        }
        val actualNCycles = if (actualCycleLength == 2) { //if the actual length is equal to to
          numberOfCycles + 1 //it is a proper new cycle
        } else {
          numberOfCycles // no new cycles
        }
        (actualNCycles, actualCycleLength, numberSign) //return the actual state
      }
    }
    result._1 //get the final number of cycles
  }
scala> case class X(a:Int, b:Int, c:String)
defined class X

scala> val x = X(1,2,"a")
x: X = X(1,2,a)

scala> x.productIterator.toList
res1: List[Any] = List(1, 2, a)