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()
}
}
