您可以首先使用[]
字符串运算符来获取子字符串,而不是substring
删除中间变量。例如在以下情况下length == 10
:
"${isbn[0]}-${isbn[1..6]}-${isbn[7..8]}-${isbn[9]}"
现在,那里有一些重复。相反,您可以先获取所有isbn
细分,然后再.join
使用'-'
:
[isbn[0], isbn[1..6], isbn[7..8], isbn[9]].join('-')
而且,更进一步,isbn
您可以列出您想要获取的范围,然后使用以下命令同时获取它们,而不是每次都引用collect
:
[0, 1..6, 7..8, 9].collect { isbn[it] }.join('-')
如果您要进行代码打高尔夫球,您还可以执行以下操作:
('-'+isbn)[1, 0, 2..7, 0, 8..9, 0, 10]
我会让你弄清楚它是如何工作的,但我想把它留在生产代码上可能不是一个好主意,除非你想给未来的维护者一个惊喜,呵呵。
此外,请注意格式 whenlength == 13
与 for 相同length == 10
但具有不同的前缀,然后您可以在这种情况下重用相同的函数。整个功能(通过几个测试)将是:
/**
* 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'
现在,我认为该代码中有一些难闻的气味。可以isbn
吗null
?至少对我来说,这看起来不像是一个需要担心其参数的无效性的函数,或者至少通过阅读它的名称并不清楚(formatIsbnOrNull
如果 ISBN 字符串和 null 值都是公认)。NullPointerException
如果 null 值无效,则在访问时让它爆炸,isbn.length()
以便调用者知道他们传递了错误的参数,而不是默默地返回相同的 null。
最后也是一样return ISBN
。该函数是否期望接收一个既不是 10 也不是 13 个字符长的字符串?如果没有,最好throw new IllegalArgumentException()
让来电者知道他们打错了电话。
最后,我不确定这是否是最“可读”的解决方案。另一种可能的解决方案是为格式设置一个字符串,例如'###-#-######-##-#'
然后将#
s 替换为isbn
字符。我认为它可能更自我记录:
def formatIsbn(isbn) {
def format = [
10: '#-######-##-#',
13: '###-#-######-##-#'
][isbn.length()]
def n = 0
format.replaceAll(/#/) { isbn[n++] }
}