Hi,
Let's say we have the following code:
use std::collections::HashMap;
fn main() {
let src = "FÖÖ BÄR baz foo abc def BÄR";
let mut case_sensitive = HashMap::new();
let mut case_insensitive = HashMap::new();
for x in src.split(' ') {
case_sensitive.entry(x).or_insert(());
// Is there anything better than allocating a new `String`?
let x_i: String = x.to_lowercase();
case_insensitive.entry(x_i).or_insert(());
}
dbg!(case_sensitive);
dbg!(case_insensitive);
}
What would be the most efficient way to get a HashMap
whose keys are lower-case, so it's possible to do lookups that are case-insensitive?
One idea I had, was to allocate a String
to which the case-insensitive values are written, and then lower-case this string:
use std::collections::HashMap;
fn main() {
let src = "FÖÖ BÄR baz foo abc def BÄR";
let mut case_sensitive = HashMap::new();
let mut case_insensitive = String::new();
for x in src.split(' ') {
case_sensitive.entry(x).or_insert(());
case_insensitive.push_str(x);
case_insensitive.push(' ');
}
let case_insensitive = case_insensitive.to_lowercase();
let case_insensitive: HashMap<&str, ()> = case_insensitive
.trim_end()
.split(' ')
.map(|x| (x, ()))
.collect();
dbg!(case_sensitive);
dbg!(case_insensitive);
}
This would result in three allocations (which would be fine).
Another approach I thought of, was to use something like SmartString, but I can't find a crate that has such a type that has to_lowercase
.
One problem is, that &str
can contain non-ASCII characters (without that requirement str::as_bytes
+ char::make_ascii_lowercase
+ str::from_utf8
probably could be used).
The input I actually have is cssparser::CowRcStr (which implements Deref<Target = str>
), in case that would make a difference.