From dea0a420e88fe665610091537e7ce26bf3b2596e Mon Sep 17 00:00:00 2001 From: Julian Gehring Date: Sun, 5 Oct 2014 21:30:48 +0200 Subject: [PATCH] Digitsep: Separate digit groups in integers Convert a number to a string, separating each 'k' digits by 'sep'. 'k' defaults to 3, separating by thousands. The default "," for 'sep' matches the commonly used digit separator in the US. --- LICENSE.md | 4 ++-- README.md | 9 +++++++++ src/Humanize.jl | 26 ++++++++++++++++++++++++-- test/runtests.jl | 27 ++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index abf32b4..b3f03a7 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -2,10 +2,10 @@ This package is a derived work of the MIT-licensed humanize Python library: https://github.com/jmoiron/humanize/ All original work in this package is also licensed under the MIT license: -Copyright (c) 2014 Iain Dunning +Copyright (c) 2014 Iain Dunning, Julian Gehring Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index d6f2a85..1212e03 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Humanize.jl Humanize numbers, including * data sizes (`3e6 -> 3.0 MB or 2.9 MiB`). * Date/datetime differences (`Date(2014,2,3) - Date(2013,3,7) -> 1 year, 1 month`) +* Digit separator (`12345678 -> 12,345,678`) This package is MIT licensed, and is based on [jmoiron's humanize Python library](https://github.com/jmoiron/humanize/). @@ -55,3 +56,11 @@ julia> timedelta(Date(2014,3,7) - Date(2013,2,4)) "1 year, 1 month" ``` +### Digit separator + +```julia +julia> digitsep(12345678) +"12,345,678" +julia> digitsep(12345678, sep = "'") +"12'345'678" +``` diff --git a/src/Humanize.jl b/src/Humanize.jl index 48d266b..751c945 100644 --- a/src/Humanize.jl +++ b/src/Humanize.jl @@ -13,7 +13,7 @@ else import Base.Dates end -export datasize, timedelta +export datasize, timedelta, digitsep #=--------------------------------------------------------------------- Format a number of bytes in a human-friendly format (eg. 10 kB). @@ -85,4 +85,26 @@ timedelta{T<:Integer}(years::T,months::T,days::T,hours::T,mins::T,secs::T) = timedelta(dt_diff::Dates.Millisecond) = timedelta(div(int(dt_diff),1000)) timedelta(d_diff::Dates.Day) = timedelta(int(d_diff)*24*3600) -end \ No newline at end of file + +#=--------------------------------------------------------------------- +Convert an integer to a string, separating each 'k' digits by 'sep'. 'k' +defaults to 3, separating by thousands. The default "," for 'sep' matches the +commonly used digit separator in the US. + +digitsep(value::Integer) + e.g. 12345678 -> "12,345,678" +digitsep(value::Integer, sep = "'") + e.g. 12345678 -> "12'345'678" +digitsep(value::Integer, sep = "'", k = 4) + e.g. 12345678 -> "1234'5678" +=# + +function digitsep(value::Integer, sep = ",", k = 3) + value = string(value) + n = length(value) + starts = reverse([n:-k:1]) + groups = [value[max(x-k+1, 1):x] for x in starts] + return join(groups, sep) +end + +end diff --git a/test/runtests.jl b/test/runtests.jl index 57e692a..d0d3b79 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -78,5 +78,30 @@ function test_timedelta() end +function test_digitsep() + println("test_digitsep") + + test = ( + (1, "1"), + (12, "12"), + (123, "123"), + (1234, "1,234"), + (12345, "12,345"), + (123456, "123,456"), + (1234567, "1,234,567"), + (12345678, "12,345,678") + ) + + n_test = length(test) + + #digitsep(value::Integer) + println(" direct") + for t in test + @test digitsep(t[1]) == t[2] + end + +end + test_datasize() -test_timedelta() \ No newline at end of file +test_timedelta() +test_digitsep()