Primero podría usar el operador de cadena []
para obtener las subcadenas en lugar de substring
y soltar las variables intermedias. Por ejemplo, en el caso de length == 10
:
"${isbn[0]}-${isbn[1..6]}-${isbn[7..8]}-${isbn[9]}"
Ahora, hay un poco de repetición allí. Usted puede obtener su lugar primero obtener todos los isbn
segmentos y luego .join
con '-'
:
[isbn[0], isbn[1..6], isbn[7..8], isbn[9]].join('-')
Y, aún más, en lugar de hacer referencia a isbn
cada vez, puede hacer una lista de los rangos que desea obtener y luego llegar a todos ellos al mismo tiempo utilizando collect
:
[0, 1..6, 7..8, 9].collect { isbn[it] }.join('-')
Si vas código para jugar al golf, también se puede hacer:
('-'+isbn)[1, 0, 2..7, 0, 8..9, 0, 10]
Te dejaré que descubras cómo funciona eso, pero supongo que probablemente no sea una buena idea dejar eso en el código de producción, a menos que quieras sorprender a los futuros mantenedores jeje.
Además, observe que el formato cuando length == 13
es el mismo que para length == 10
pero con un prefijo diferente, a continuación, puede volver a utilizar la misma función que en ese caso. La función entera (con un par de pruebas) sería:
/**
* 10 digit - #-######-##-#
* 13 digit - ###-#-######-##-#
**/
def formatIsbn(isbn) {
switch (isbn?.length()) {
case 10: return [0, 1..6, 7..8, 9].collect { isbn[it] }.join('-')
case 13: return isbn.take(3) + '-' + formatIsbn(isbn.drop(3))
default: return isbn
}
}
assert formatIsbn('abcdefghij') == 'a-bcdefg-hi-j'
assert formatIsbn('abcdefghijklm') == 'abc-d-efghij-kl-m'
ahora, creo que hay algunos malos olores en ese código. ¿Puede isbn
ser null
? Al menos para mí, esto no parece una función que necesite preocuparse por la nulidad de su argumento, o al menos no está claro al leer su nombre (debería llamarse algo así como formatIsbnOrNull
en vez de cadenas de ISBN y valores nulos) son aceptados). Si los valores nulos no son válidos, déjalo explotar con un NullPointerException
al acceder al isbn.length()
para que la persona que llama sepa que ha pasado un argumento incorrecto, en lugar de devolver silenciosamente el mismo valor nulo.
Lo mismo ocurre con el return ISBN
al final. ¿Se espera que esa función reciba una cadena que no tiene 10 ni 13 caracteres de largo? De lo contrario, mejor throw new IllegalArgumentException()
y avise a la persona que llama que lo han llamado incorrectamente.
Finalmente, no estoy seguro de si esta es la solución más "legible". Otra posible solución es tener una cadena para el formato, como '###-#-######-##-#'
y luego reemplazar el #
por los caracteres isbn
. Creo que podría ser más auto-documentado:
def formatIsbn(isbn) {
def format = [
10: '#-######-##-#',
13: '###-#-######-##-#'
][isbn.length()]
def n = 0
format.replaceAll(/#/) { isbn[n++] }
}
Puede explicar el * se separe? ¿Qué hace * en ese caso? – Gregg
@Gregg Desestructura la matriz para que se vea como los dos parámetros de subcadena individuales. Sin embargo, debería funcionar sin eso, creo. No podría decirte por qué lo haría, sin embargo, por eso era pollo y lo dejé. –