Skip to content

Commit b90d0b3

Browse files
authored
Rollup merge of rust-lang#70996 - ChaiTRex:master, r=Amanieu
Add or_insert_with_key to Entry of HashMap/BTreeMap Going along with `or_insert_with`, `or_insert_with_key` provides the `Entry`'s key to the lambda, avoiding the need to either clone the key or the need to reimplement this body of this method from scratch each time. This is useful when the initial value for a map entry is derived from the key. For example, the introductory Rust book has an example Cacher struct that takes an expensive-to-compute lambda and then can, given an argument to the lambda, produce either the cached result or execute the lambda. --- I'm fairly new to Rust, so any optimizations, corrections to types, better names, better documentation, or whatever else would be appreciated. I'd like to thank Arnavion on freenode for helping me to implement a very similar method when I found that `or_insert_with_key` was unavailable. As a somewhat-related note, this implements rust-lang/rfcs#1202 from 2015, so if this pull request is accepted, that should be closed.
2 parents 6bad3ee + db0c39f commit b90d0b3

File tree

2 files changed

+56
-0
lines changed
  • src
    • liballoc/collections/btree
    • libstd/collections/hash

2 files changed

+56
-0
lines changed

src/liballoc/collections/btree/map.rs

+28
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,34 @@ impl<'a, K: Ord, V> Entry<'a, K, V> {
23612361
}
23622362
}
23632363

2364+
#[unstable(feature = "or_insert_with_key", issue = "71024")]
2365+
/// Ensures a value is in the entry by inserting, if empty, the result of the default function,
2366+
/// which takes the key as its argument, and returns a mutable reference to the value in the
2367+
/// entry.
2368+
///
2369+
/// # Examples
2370+
///
2371+
/// ```
2372+
/// #![feature(or_insert_with_key)]
2373+
/// use std::collections::BTreeMap;
2374+
///
2375+
/// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
2376+
///
2377+
/// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
2378+
///
2379+
/// assert_eq!(map["poneyland"], 9);
2380+
/// ```
2381+
#[inline]
2382+
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
2383+
match self {
2384+
Occupied(entry) => entry.into_mut(),
2385+
Vacant(entry) => {
2386+
let value = default(entry.key());
2387+
entry.insert(value)
2388+
}
2389+
}
2390+
}
2391+
23642392
/// Returns a reference to this entry's key.
23652393
///
23662394
/// # Examples

src/libstd/collections/hash/map.rs

+28
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,34 @@ impl<'a, K, V> Entry<'a, K, V> {
19431943
}
19441944
}
19451945

1946+
#[unstable(feature = "or_insert_with_key", issue = "71024")]
1947+
/// Ensures a value is in the entry by inserting, if empty, the result of the default function,
1948+
/// which takes the key as its argument, and returns a mutable reference to the value in the
1949+
/// entry.
1950+
///
1951+
/// # Examples
1952+
///
1953+
/// ```
1954+
/// #![feature(or_insert_with_key)]
1955+
/// use std::collections::HashMap;
1956+
///
1957+
/// let mut map: HashMap<&str, usize> = HashMap::new();
1958+
///
1959+
/// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
1960+
///
1961+
/// assert_eq!(map["poneyland"], 9);
1962+
/// ```
1963+
#[inline]
1964+
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
1965+
match self {
1966+
Occupied(entry) => entry.into_mut(),
1967+
Vacant(entry) => {
1968+
let value = default(entry.key());
1969+
entry.insert(value)
1970+
}
1971+
}
1972+
}
1973+
19461974
/// Returns a reference to this entry's key.
19471975
///
19481976
/// # Examples

0 commit comments

Comments
 (0)