rust


How to convert char to integer so that '1' becomes 1?


I am trying to find sum of all the digits of a given number, like 134 gives 8.
My plan is to iterate over the number by converting it into a string using .to_string() and then use .chars() to iterate over the number. Then I want to convert every char in the iteration into an integer and add into a variable. I want to get the final value of this variable.
I tried using the code below to convert a char into an integer (Playground):
fn main() {
let x = "123";
for y in x.chars() {
let z = y.parse::<i32>().unwrap();
println!("{}", z + 1);
}
}
But it results in this error:
error: no method named `parse` found for type `char` in the current scope
--> <anon>:4:19
|
4 | let z = y.parse::<i32>().unwrap();
| ^^^^^
How can I convert a char into an integer?
The below code does exactly what I want to do (Playground):
fn main() {
let mut sum = 0;
let x = 123;
let x = x.to_string();
for y in x.chars() {
// converting `y` to string and then to integer
let z = (y.to_string()).parse::<i32>().unwrap();
// incrementing `sum` by `z`
sum += z;
}
println!("{}", sum);
}
but first I have to convert char into a string and then into an integer to increment sum by z. Is there a way to directly convert char into integer?
The method you need is char::to_digit. It converts char to a number it represents in the given radix.
You can also use Iterator::sum to calculate sum of a sequence conveniently:
fn main() {
const RADIX: u32 = 10;
let x = "134";
println!("{}", x.chars().map(|c| c.to_digit(RADIX).unwrap()).sum::<u32>());
}
my_char as u32 - '0' as u32
Now, there's a lot more to unpack about this answer.
It works because the ASCII (and thus UTF-8) encodings have the Arabic numerals 0-9 ordered in ascending order. You can get the scalar values and subtract them.
However, what should it do for values outside this range? What happens if you provide 'p'? It returns 64. What about '.'? This will panic. And '♥' will return 9781.
Strings are not just bags of bytes. They are UTF-8 encoded and you cannot just ignore that fact. Every char can hold any Unicode scalar value.
That's why strings are the wrong abstraction for the problem.
From an efficiency perspective, allocating a string seems inefficient. Rosetta Code has an example of using an iterator which only does numeric operations:
struct DigitIter(usize, usize);
impl Iterator for DigitIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.0 == 0 {
None
} else {
let ret = self.0 % self.1;
self.0 /= self.1;
Some(ret)
}
}
}
fn main() {
println!("{}", DigitIter(1234, 10).sum::<usize>());
}
The method parse() is defined on str, not on char. A char is a Unicode codepoint, which is 32 bits wide. If you cast it to an integer, using u32 is preferred over i32.
You can cast it via as or into():
let a = '♥' as u32;
let b: u32 = '♥'.into();
Another way is to iterate over the characters of your string and convert and add them using fold.
fn sum_of_string(s: &str) -> u32 {
s.chars().fold(0, |acc, c| c.to_digit(10).unwrap_or(0) + acc)
}
fn main() {
let x = "123";
println!("{}", sum_of_string(x));
}

Related Links

Issues constraining implementation lifetimes on type without lifetime parameter
How to use recursive associated types in functions?
Right way to share a reference between closures
Borrow checker and function arguments in Rust, correct or over zealous?
Most idiomatic way to create a default struct
How to return an Iterator from a Map [duplicate]
Do all primitive types implement the Copy trait?
Comparison of two floats in Rust to arbitrary level of precision
Is there a convenient way to represent x86 instructions in a struct or other language feature?
Why isn't `regex!` a wrapper for `Regex::new` to offer the same regex matching speed?
Lifetime annotation for closure argument
“overflow while adding drop-check rules” while implementing a fingertree
Is it possible to coerce slices/vectors into 'Cow<[type]>' in function arguments?
Unable to get started with diesel.rs and Rust 1.16 nightly
Do all generic types implement the Copy trait?
How to add code only for specific Rust version without using a build script?

Categories

HOME
google-chrome
oracle
entity-framework
user-interface
mod-rewrite
generics
opencart
google-play-services
dependencies
moodle-api
clone
haxe
supercollider
firebase-dynamic-links
tweepy
port
hspi
driver
scrape
documentum
buffer
android-externalstorage
squirrel-sql
sql-injection
tomcat8
checkout
office-ui-fabric
gmp
nullreferenceexception
scheduled-tasks
pfobject
adminlte
jest
web-analytics
backtracking
conda
quantitative-finance
python-appium
uilocalnotification
ccavenue
javax.persistence
basic-authentication
netbios
quick-nimble
wampsharp
sca
shapeless
sql-execution-plan
counting
creation
jade4j
extbase
plane
classnotfoundexception
vb.net-to-c#
intellij-lombok-plugin
sony-future-lab-n
karabiner
sonatype
scala-collections
ptvs
stateless-session-bean
email-forwarding
dynamics-crm-4
google-shopping-api
maatwebsite-excel
portal
bilinear-interpolation
spring-mongo
apache-pig-grunt
adjacency-list
timestamping
processor
verisign
wif4.5
django-validation
voronoi
webgrind
perceptron
featuretoggle
console.log
gflags
mathematical-expressions
storing-data
git-reset
jack
accountmanager
assetic
armv6
postgres-xc
dojo-1.9
gprof
getopt-long
viewpagerindicator
jdom
space-partitioning
azure-acs
jquery-1.4
ognl
bll
cassini
tessellation
self-tracking-entities
3270
isapi-redirect

Resources

Encrypt Message