Is there an easy way to convert a number to a letter?
For example,
3 => "C" and 23 => "W"?
For simplicity range check is omitted from below solutions.
They all can be tried on the Go Playground.
Number -> rune
Simply add the number to the const 'A' - 1 so adding 1 to this you get 'A', adding 2 you get 'B' etc.:
func toChar(i int) rune {
return rune('A' - 1 + i)
}
Testing it:
for _, i := range []int{1, 2, 23, 26} {
fmt.Printf("%d %q\n", i, toChar(i))
}
Output:
1 'A'
2 'B'
23 'W'
26 'Z'
Number -> string
Or if you want it as a string:
func toCharStr(i int) string {
return string('A' - 1 + i)
}
Output:
1 "A"
2 "B"
23 "W"
26 "Z"
This last one (converting a number to string) is documented in the Spec: Conversions to and from a string type:
Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer.
Number -> string (cached)
If you need to do this a lot of times, it is profitable to store the strings in an array for example, and just return the string from that:
var arr = [...]string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
func toCharStrArr(i int) string {
return arr[i-1]
}
Note: a slice (instead of the array) would also be fine.
Note #2: you may improve this if you add a dummy first character so you don't have to subtract 1 from i:
var arr = [...]string{".", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
func toCharStrArr(i int) string { return arr[i] }
Number -> string (slicing a string constant)
Also another interesting solution:
const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
func toCharStrConst(i int) string {
return abc[i-1 : i]
}
Slicing a string is efficient: the new string will share the backing array (it can be done because strings are immutable).
If you need not a rune, but a string and also more than one character for e.g. excel column
package main
import (
"fmt"
)
func IntToLetters(number int32) (letters string){
number--
if firstLetter := number/26; firstLetter >0{
letters += IntToLetters(firstLetter)
letters += string('A' + number%26)
} else {
letters += string('A' + number)
}
return
}
func main() {
fmt.Println(IntToLetters(1))// print A
fmt.Println(IntToLetters(26))// print Z
fmt.Println(IntToLetters(27))// print AA
fmt.Println(IntToLetters(1999))// print BXW
}
preview here: https://play.golang.org/p/GAWebM_QCKi
I made also package with this: https://github.com/arturwwl/gointtoletters
The simplest solution would be
func stringValueOf(i int) string {
var foo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
return string(foo[i-1])
}
Hope this will help you to solve your problem. Happy Coding!!
Related
I cannot find the correct solution or I get an error for something that is very simple in C: how can I convert/move data from a table to string?
The C equivalent of what I am trying to do is:
for (i=0; i <10; i++)
{
string[i] = table[i]
}
I can convert from string to table with :byte(i) but I don't understand how to append a sign in string.
To create a string from all values in a table you can use table.concat, this will concatenate each character in a table.
local myTable = { "h", "e", "l", "l", "o" }
local combinedString = table.concat(myTable)
print(combinedString) -- Outputs hello
Run Code Demo
I have been trying to wrap my head around something and can't seem to find an answer. I know how to get all the permutations of a string as it is fairly easy. What I want to try and do is get all the permutations of the string in different sizes. For example:
Given "ABCD" and a lower limit of 3 chars I would want to get back ABC, ABD, ACB, ACD, ADB, ADC, ... , ABCD, ACBD, ADBC, .. etc.
I'm not quite sure how to accomplish that. I have it in my head that it is something that could be very complicated or very simple. Any help pointing me in a direction is appreciated. Thanks.
If you've already got the full-length permutations, you can drop stuff off of the front or back, and insert the result into a set.
XCTAssertEqual(
Permutations(["A", "B", "C"]).reduce( into: Set() ) { set, permutation in
permutation.indices.forEach {
set.insert( permutation.dropLast($0) )
}
},
[ ["A", "B", "C"],
["A", "C", "B"],
["B", "C", "A"],
["B", "A", "C"],
["C", "A", "B"],
["C", "B", "A"],
["B", "C"],
["C", "B"],
["C", "A"],
["A", "C"],
["A", "B"],
["B", "A"],
["A"],
["B"],
["C"]
]
)
public struct Permutations<Sequence: Swift.Sequence>: Swift.Sequence, IteratorProtocol {
public typealias Array = [Sequence.Element]
private let array: Array
private var iteration = 0
public init(_ sequence: Sequence) {
array = Array(sequence)
}
public mutating func next() -> Array? {
guard iteration < array.count.factorial!
else { return nil }
defer { iteration += 1 }
return array.indices.reduce(into: array) { permutation, index in
let shift =
iteration / (array.count - 1 - index).factorial!
% (array.count - index)
permutation.replaceSubrange(
index...,
with: permutation.dropFirst(index).shifted(by: shift)
)
}
}
}
public extension Collection where SubSequence: RangeReplaceableCollection {
func shifted(by shift: Int) -> SubSequence {
let drops =
shift > 0
? (shift, count - shift)
: (count + shift, -shift)
return dropFirst(drops.0) + dropLast(drops.1)
}
}
public extension BinaryInteger where Stride: SignedInteger {
/// - Note: `nil` for negative numbers
var factorial: Self? {
switch self {
case ..<0:
return nil
case 0...1:
return 1
default:
return (2...self).reduce(1, *)
}
}
}
Just wondering if there will be performance differences in running str_replace_all.
For example:
text <- c("a","b", "c")
str_replace_all(text, c("a", "b", "c"), c("d", "e", "f"))
and
str_replace_all(text, "a", "d")
str_replace_all(text, "b", "e")
str_replace_all(text, "c", "f")
Both get me the same result but I was wondering what would be faster if I was doing the same procedure for close to 200,000 documents and if each document file was longer?
It is evident you will have better performance with a single str_replace_all call since you do not have to change text value. See, when you need to call str_replace_all to change the text value, you need to re-assign the value each time you replace and that means additional overhead.
Here is a test with 3 functions: f1 uses the first approach, f2 uses the second and f3 is just a "chained" version of f2:
> library(microbenchmark)
> text <- c("a", "b", "c")
> f1 <- function(text) { text=str_replace_all(text, "a", "d"); text = str_replace_all(text, "b", "e"); text=str_replace_all(text, "c", "f"); return(text) }
> f1(text)
[1] "d" "e" "f"
> f2 <- function(text) { return(str_replace_all(text, c("a", "b", "c"), c("d", "e", "f"))) }
> f2(text)
[1] "d" "e" "f"
> f3 <- function(text) { return(str_replace_all(str_replace_all(str_replace_all(text, "c", "f"), "b", "e"), "a", "d")) }
> f3(text)
[1] "d" "e" "f"
> test <- microbenchmark( f1(text), f2(text), f3(text), times = 50000 )
> test
Unit: microseconds
expr min lq mean median uq max neval
f1(text) 225.788 233.335 257.2998 239.673 262.313 25071.76 50000
f2(text) 182.321 187.755 207.1858 191.980 210.393 24844.76 50000
f3(text) 224.581 231.825 255.2167 237.863 259.898 24531.74 50000
With times = 50000, the functions were run 50,000 times and the median value, being the lowest with f2, together with lower quartile (lq) and upper quartile (uq) values, proves that a single str_replace_all is the fastest. autoplot(test) (from ggplot2 library) shows:
And finally, it is best to use stri_replace_all_fixed from stringi package if you need to only replace literal strings. Then, here is the benchmark:
> library(stringi)
> f1 <- function(text) { text=stri_replace_all_fixed(text, "a", "d"); text = stri_replace_all_fixed(text, "b", "e"); text=stri_replace_all_fixed(text, "c", "f"); return(text) }
> f2 <- function(text) { return(stri_replace_all_fixed(text, c("a", "b", "c"), c("d", "e", "f"))) }
> f3 <- function(text) { return(stri_replace_all_fixed(stri_replace_all_fixed(stri_replace_all_fixed(text, "c", "f"), "b", "e"), "a", "d")) }
> test <- microbenchmark( f1(text), f2(text), f3(text), times = 50000 )
> test
Unit: microseconds
expr min lq mean median uq max neval cld
f1(text) 7.547 7.849 9.197490 8.151 8.453 1008.800 50000 b
f2(text) 3.321 3.623 4.420453 3.925 3.925 2053.821 50000 a
f3(text) 7.245 7.547 9.802766 7.849 8.151 50816.654 50000 b
I want a function func format(s []string) string such that for two string slices s1 and s2, if reflect.DeepEqual(s1, s2) == false, then format(s1) != format(s2).
If I simply use fmt.Sprint, slices ["a", "b", "c"] and ["a b", "c"] are all printed as [a b c], which is undesirable; and there is also the problem of string([]byte('4', 0, '2')) having the same representation as "42".
Use a format verb that shows the data structure, like %#v. In this case %q works well too because the primitive types are all strings.
fmt.Printf("%#v\n", []string{"a", "b", "c"})
fmt.Printf("%#v\n", []string{"a b", "c"})
// prints
// []string{"a", "b", "c"}
// []string{"a b", "c"}
You may use:
func format(s1, s2 []string) string {
if reflect.DeepEqual(s1, s2) {
return "%v\n"
}
return "%q\n"
}
Like this working sample (The Go Playground):
package main
import (
"fmt"
"reflect"
)
func main() {
s1, s2 := []string{"a", "b", "c"}, []string{"a b", "c"}
frmat := format(s1, s2)
fmt.Printf(frmat, s1) // ["a" "b" "c"]
fmt.Printf(frmat, s2) // ["a b" "c"]
s2 = []string{"a", "b", "c"}
frmat = format(s1, s2)
fmt.Printf(frmat, s1) // ["a" "b" "c"]
fmt.Printf(frmat, s2) // ["a b" "c"]
}
func format(s1, s2 []string) string {
if reflect.DeepEqual(s1, s2) {
return "%v\n"
}
return "%q\n"
}
output:
["a" "b" "c"]
["a b" "c"]
[a b c]
[a b c]
I'm trying to append Character to String using "+=", but It doesn't really work.
Once I tried with append method, it works. I just wonder why it is.
The compiler says "string is not identical to Unit8".
let puzzleInput = "great minds think alike"
var puzzleOutput = " "
for character in puzzleInput {
switch character {
case "a", "e", "i", "o", "u", " ":
continue
default:
// error : doesn't work
puzzleOutput += character
//puzzleOutput.append(character)
}
}
println(puzzleOutput)
20140818, Apple updated:
Updated the Concatenating Strings and Characters section to reflect the fact that String and Character values can no longer be combined with the addition operator (+) or addition assignment operator (+=). These operators are now used only with String values. Use the String type’s append method to append a single Character value onto the end of a string.
Document Revision History 2014-08-18
To append a Character to a String in Swift you can do something similar to the following:
var myString: String = "ab"
let myCharacter: Character = "c"
let myStringChar: String = "d"
myString += String(myCharacter) // abc
myString += myStringChar // abcd
Updated version
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput.characters {
switch character {
case "a", "e", "i", "o", "u", " ":
continue
default:
puzzleOutput += String(character)
}
}
print(puzzleOutput)
// prints "grtmndsthnklk"