Search code examples
arrayslistscalatail

What is the Best way to loop over an array in scala


I'm new to scala and I'm trying to refactor the below code.I want to eliminate "index" used in the below code and loop over the array to fetch data.

 subgroupMetricIndividual.instances.foreach { instanceIndividual =>
   val MetricContextListBuffer: ListBuffer[Context] = ListBuffer()
   var index = 0
   contextListBufferForSubGroup.foreach { contextIndividual =>
        MetricContextListBuffer += Context(
                 entity = contextIndividual,
                 value = instanceIndividual(index).toString
        )
        index += 1
   }
}

For instance, if the values of variables are as below:

contextListBufferForSubGroup = ("context1","context2")
subgroupMetricIndividual.instances = {{"Inst1","Inst2",1},{"Inst3","Inst4",2}}

Then Context should be something like:

  { 
   entity: "context1",
   value:  "Inst1"
   },
   { 
   entity: "context2",
   value:  "Inst2"
   },
   { 
   entity: "context1",
   value:  "Inst3"
   },
   { 
   entity: "context2",
   value:  "Inst4"
   }

Note:

instanceIndividual can have more elements than those in contextListBufferForSubGroup. We must ignore the last extra elements in instanceIndividual in this case


Solution

  • You can zip two lists into a list of tuples and then map over that. e.g.

    subgroupMetricIndividual.instances.foreach { instanceIndividual =>
      val MetricContextListBuffer = contextListBufferForSubGroup.zip(instanceIndividual).map {
        case (contextIndividual, instanceIndividualIndex) => Context(
          entity = contextIndividual,
          value = instanceIndividualIndex.toString
        )
      }
    }
    

    If Context can be called like a function i.e. Context(contextIndividual, instanceIndividualIndex.toString) then you can write this even shorter.

    subgroupMetricIndividual.instances.foreach { instanceIndividual =>
      val MetricContextListBuffer = contextListBufferForSubGroup
        .zip(instanceIndividual.map(_.toString)).map(Context.tupled)
    }