Trước tiên, bạn có thể sử dụng toán tử chuỗi []
để lấy các bản chất thay vì substring
và thả các biến trung gian. Ví dụ: trong trường hợp cho length == 10
:
"${isbn[0]}-${isbn[1..6]}-${isbn[7..8]}-${isbn[9]}"
Bây giờ, có một chút lặp lại ở đó. Bạn có thể nhận thay vì đầu tiên nhận được tất cả các isbn
phân đoạn và sau đó .join
chúng với '-'
:
[isbn[0], isbn[1..6], isbn[7..8], isbn[9]].join('-')
Và, hơn nữa, thay vì tham khảo isbn
mọi thời gian, bạn có thể tạo ra một danh sách các phạm vi bạn muốn nhận được và sau đó nhận được tất cả đồng thời sử dụng collect
:
[0, 1..6, 7..8, 9].collect { isbn[it] }.join('-')
Nếu bạn đang đi cho mã chơi golf, bạn cũng có thể làm:
('-'+isbn)[1, 0, 2..7, 0, 8..9, 0, 10]
Tôi sẽ để nó cho bạn để tìm ra cách thức hoạt động, nhưng tôi đoán có lẽ không phải là một ý tưởng tốt để để lại điều đó trên mã sản xuất, trừ khi bạn muốn gây bất ngờ cho các nhà bảo trì tương lai hehe.
Ngoài ra, hãy chú ý rằng các định dạng khi length == 13
cũng giống như đối với length == 10
nhưng với một tiền tố khác nhau, bạn có thể tái sử dụng các chức năng tương tự trong trường hợp đó. Toàn bộ chức năng (với một vài bài kiểm tra) sẽ là:
/**
* 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'
Bây giờ, tôi nghĩ rằng có một số mùi hôi trong mã đó. Có thể isbn
là null
? Ít nhất với tôi, điều này không giống như một hàm cần phải bận tâm về sự vô hiệu của đối số của nó, hoặc ít nhất nó không rõ ràng bằng cách đọc tên của nó (nó phải được gọi là formatIsbnOrNull
thay thế nếu cả hai chuỗi ISBN và giá trị null được cháp nhận). Nếu giá trị null không hợp lệ, sau đó để cho nó nổ tung với một NullPointerException
khi truy cập isbn.length()
để người gọi biết rằng họ đã vượt qua một đối số sai, thay vì âm thầm trả về cùng một giá trị rỗng.
Tương tự như vậy đối với số return ISBN
ở cuối. Nó có được mong đợi cho chức năng đó để nhận một chuỗi dài 10 ký tự không? Nếu không, tốt hơn throw new IllegalArgumentException()
và để cho người gọi biết họ đã gọi sai.
Cuối cùng, tôi không chắc đây có phải là giải pháp "dễ đọc" nhất hay không. Một giải pháp khả thi khác là có chuỗi cho định dạng, như '###-#-######-##-#'
và sau đó thay thế #
s theo các ký tự isbn
. Tôi nghĩ rằng nó có thể có nhiều tự chủ tài liệu:
def formatIsbn(isbn) {
def format = [
10: '#-######-##-#',
13: '###-#-######-##-#'
][isbn.length()]
def n = 0
format.replaceAll(/#/) { isbn[n++] }
}
Bạn có thể giải thích * nó một phần? * Làm gì trong trường hợp đó? – Gregg
@Gregg Nó de-cấu trúc mảng vì vậy nó trông giống như hai tham số chuỗi con cá nhân. Nó sẽ làm việc mà không có nó, mặc dù, tôi nghĩ. Tôi không thể cho bạn biết tại sao nó sẽ, mặc dù, đó là lý do tại sao tôi là gà và để nó trong. –