Kundan Kumar
Kundan Kumar

Reputation: 2002

Yield Inside Nested for Loop in Scala not returning anything

I am new to Scala. In the code below I am trying to return value from classing_summary function but I am facing trouble using the yield function. Here, I want to yield multiple values from inside the nested for loop.

Currently it does not return anything.

How to fix the code?

def classing_summary(arr: Array[(Double, Int)]) = {
      var value = 0.0
      var freq = 1
      var prevValue = Double.MinValue
      var bin = 1
      var classSize = 0.0
      var size = arr.length
      val tCount = arr.map{case (x,y) => y}.sum
      val output = for(i <- 0 until size) yield
      {
          value = arr(i)._1
          freq = arr(i)._2
          if(freq/tCount >= 0.05)
          { 
            for(j <- 0 until freq) yield
            {
              classSize += 1/tCount;
              (value,bin,classSize);
            }
            classSize = 0.0
            bin +=1
          }
          else
          {
            for(j <- 0 until freq ) yield
            {
              classSize += 1/tCount;
              (value,bin,classSize);
            }
            if(classSize >= 0.05)
            {
                 classSize = 0.0;
                 bin += 1;
            }
          }
      }
      output.toArray
    }

Upvotes: 0

Views: 738

Answers (1)

dk14
dk14

Reputation: 22374

It doesn't return anything because your:

  if (classSize >= 0.05) {
     classSize = 0.0
     bin += 1
  }

doesn't return anything. Just save the value in advance:

  val r = for(j <- 0 until freq ) yield {
          classSize += 1/tCount;
          (value,bin,classSize);
  }

  if(classSize >= 0.05) {
        classSize = 0.0;
        bin += 1;
  }
  r

Your code (at least inside first for) could be optimized by the way:

  val r = for(j <- 0 until freq) yield {
      classSize += 1/tCount
      (value,bin,classSize)
  }

  if (freq/tCount >= 0.05 || classSize >= 0.05) {
      classSize = 0.0
      bin += 1;
  } 
  r

Even more:

  case class Data(value: Int = 0, bin: Boolean = 0, classSize: Int = 0, data: List[List[(Int, Int, Int)]])

  arr.foldLeft(Data()) {
      case ((value, freq), acc) =>
        val data = for(i <- 0 until freq) //generate data
          yield (value, bin, acc.classSize + i/tCount)

        val (bin, classSize) = //calculate new `bin` and `classSize`
          if (freq/tCount >= 0.05 || classSize >= 0.05)   
            (acc.bin + 1, classSize + freq / tCount)
          else (acc.bin, 0)

        Data(value, bin, classSize, acc.data :+ data) //accumulate
  } data

Upvotes: 2

Related Questions