6

I have a HashMap<(String, usize), f64>. I also have a &str and a usize, which I would like to look up in this HashMap without cloning. Is there a way to lookup a (&str, usize) as a (String, usize) somehow?

yong
  • 3,583
  • 16
  • 32
  • 1
    If possible, you must use `Cow`, see http://stackoverflow.com/questions/36480845/how-to-avoid-temporary-allocations-when-using-complex-key-for-hashmap – tafia Jun 15 '16 at 08:51
  • Any reason you don't want to use `HashMap<(&str, usize), f64>`? It could be that I don't understand rust well enough but that seems like a reasonable solution to me. – user25064 Jun 15 '16 at 11:55
  • 1
    @user25064 something needs to hold the allocation of the `String`, and perhaps the key of the map is the most natural. Splitting the two up is a potential solution though, depending on the usecase. – Shepmaster Jun 15 '16 at 12:37

2 Answers2

5

No, you can't. The options for looking up in the HashMap<K,V> are:

  • The entry method, which requires a K by value, which in your case is a (String, usize) - so you'd need to construct a String.
  • The various get, contains_key etc. all take a "borrowed" form of K (the documentation says &Q, where K: Borrow<Q>; this means either a &(String, usize) or something that can produced one.

Technically you could iterate through it and do your own comparisons, but that's probably not what you want!

Chris Emerson
  • 13,041
  • 3
  • 44
  • 66
  • Note that this is no longer true. With edition 2018, you can look up String keys with &str. – Kenji Mar 09 '21 at 03:59
4

There is, however, a method to do this that does not involve allocating a string. But you'll have to change your Hashmap so the key is of type (std::borrow::Cow<'a, str>, usize) (for some lifetime 'a). Then you can look up values with map.get((Cow::Borrowed(my_str_slice), 0)).

llogiq
  • 13,815
  • 8
  • 40
  • 72