Home > Blockchain >  Scala generate a collection of elements based on a number of required elements and a known first ele
Scala generate a collection of elements based on a number of required elements and a known first ele

Time:01-25

Looking for an elegant Scala way to generate a collection of elements based on a number of required elements and a known first element.

For example:

def generateListOfData(numberOfElements: Int = 1): Seq[Data] = {
if(numberOfElements == 1)
   Seq(aData(id = id)) //aData is some builder
else 
   // generate a `Seq` of elements with `id = randomInt`
}

What would be the most elegant approach to do it?

CodePudding user response:

As I always say, the Scaladoc is your friend.
You can use tabulate to get the results you want.

def generateListOfData(numberOfElements: Int = 1): Seq[Data] =
  Seq.tabulate(numberOfElements) { n =>
    if (n == 1) aData(id = id) else aData(id = randomInt)
  }

You may also use fill like this:

def generateListOfData(numberOfElements: Int = 1): Seq[Data] =
  aData(id = id) :: List.fill(numberOfElements - 1)(aData(id = randomInt))

PS: If numberOfElements is not positive the above methods will throw an exception.

CodePudding user response:

You can generate range from 1 to numberOfElements - 1 map it into Data and prepend with default element:

def generateListOfData(numberOfElements: Int = 1): Seq[Data] = {
    if (numberOfElements > 0) {
      val rnd = new scala.util.Random
      aData(id = id)  : (1 to numberOfElements - 1)
        .map(_ => aData(id = rnd.nextInt()))
    }
    Seq[Data]()
}

Or using foldLeft and pattern matching with guards:

def generateListOfData(numberOfElements: Int = 1): Seq[Data] = {
    val rnd = new scala.util.Random
    numberOfElements match {
      case _ if numberOfElements > 0 => (1 to numberOfElements - 1)
        .foldLeft(Seq(aData(id = id))) { (acc, _) => aData(id = rnd.nextInt())  : acc }
        .reverse
      case _ => Seq()
    }
}
  •  Tags:  
  • Related