Мне нужно сделать генератор URI, который использует следующий шаблон в качестве входных данных s3://base/key1=s/key2={1,2,3}/key3={4,5}
и получить из него 6 URI:
s3://base/key1=s/key2=1/key3=4
s3://base/key1=s/key2=1/key3=5
s3://base/key1=s/key2=2/key3=4
s3://base/key1=s/key2=2/key3=5
s3://base/key1=s/key2=3/key3=4
s3://base/key1=s/key2=3/key3=5
Звучит как общий комбинатор, но мне не удалось быстро найти существующий в Scala. Google отправляет мне geeksforgeeks в качестве примера, который я передаю на Scala в качестве следующего кода, пожалуйста, помогите мне сделать его короче / лучше:
def generateUrls(template: String) = {
val re = """\{[,\w]+\}""".r
val pattern = re.replaceAllIn(template, "%s")
val options = new ListBuffer[Array[String]]
for (m <- re.findAllIn(template)) {
options += m.substring(1, m.length - 1).split(',').toSet.toArray
}
val sets = combinator(options)
for(set <- sets)
yield pattern.format(set:_*)
}
def combinator[T](arr:ListBuffer[Array[T]]):Seq[Seq[T]]= {
//number of arrays
val n = arr.size
//to keep track of next element
//in each of the n arrays
val indices = Array.fill(n)(0)
val result = new ListBuffer[Seq[T]]
while (true) {
//prcurrent combination
result+= arr.zipWithIndex.map( r => r._1(indices(r._2)))
//find the rightmost array that has more
//elements left after the current element
//in that array
var next = n - 1
while (next >= 0 && indices(next) + 1 >= (arr(next).size))
next-=1
//no such array is found so no more
//combinations left
if (next < 0)
return result
//if found move to next element in that
// array
indices(next) += 1
//for all arrays to the right of this
// array current index again points to
// first element
for (i <- next + 1 to n-1)
indices(i) = 0
}
return result
}