Skip to content

Implement into_keys and into_values for associative maps #75163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 8, 2020
128 changes: 128 additions & 0 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,52 @@ where
{
self.base.retain(f)
}

/// Creates a consuming iterator visiting all the keys in arbitrary order.
/// The map cannot be used after calling this.
/// The iterator element type is `K`.
///
/// # Examples
///
/// ```
/// #![feature(map_into_keys_values)]
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// map.insert("a", 1);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it's better an example with HashMap<String> instead of HashMap<&str> ?

/// map.insert("b", 2);
/// map.insert("c", 3);
///
/// let vec: Vec<&str> = map.into_keys().collect();
/// ```
#[inline]
#[unstable(feature = "map_into_keys_values", issue = "55214")]
pub fn into_keys(self) -> IntoKeys<K, V> {
IntoKeys { inner: self.into_iter() }
}

/// Creates a consuming iterator visiting all the values in arbitrary order.
/// The map cannot be used after calling this.
/// The iterator element type is `V`.
///
/// # Examples
///
/// ```
/// #![feature(map_into_keys_values)]
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// map.insert("a", 1);
/// map.insert("b", 2);
/// map.insert("c", 3);
///
/// let vec: Vec<i32> = map.into_values().collect();
/// ```
#[inline]
#[unstable(feature = "map_into_keys_values", issue = "55214")]
pub fn into_values(self) -> IntoValues<K, V> {
IntoValues { inner: self.into_iter() }
}
}

impl<K, V, S> HashMap<K, V, S>
Expand Down Expand Up @@ -1154,6 +1200,28 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
inner: IterMut<'a, K, V>,
}

/// An owning iterator over the keys of a `HashMap`.
///
/// This `struct` is created by the [`into_keys`] method on [`HashMap`].
/// See its documentation for more.
///
/// [`into_keys`]: HashMap::into_keys
#[unstable(feature = "map_into_keys_values", issue = "55214")]
pub struct IntoKeys<K, V> {
inner: IntoIter<K, V>,
}

/// An owning iterator over the values of a `HashMap`.
///
/// This `struct` is created by the [`into_values`] method on [`HashMap`].
/// See its documentation for more.
///
/// [`into_values`]: HashMap::into_values
#[unstable(feature = "map_into_keys_values", issue = "55214")]
pub struct IntoValues<K, V> {
inner: IntoIter<K, V>,
}

/// A builder for computing where in a HashMap a key-value pair would be stored.
///
/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
Expand Down Expand Up @@ -1827,6 +1895,66 @@ where
}
}

#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K, V> Iterator for IntoKeys<K, V> {
type Item = K;

#[inline]
fn next(&mut self) -> Option<K> {
self.inner.next().map(|(k, _)| k)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K, V> FusedIterator for IntoKeys<K, V> {}

#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K: Debug, V: Debug> fmt::Debug for IntoKeys<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter()).finish()
}
}

#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K, V> Iterator for IntoValues<K, V> {
type Item = V;

#[inline]
fn next(&mut self) -> Option<V> {
self.inner.next().map(|(_, v)| v)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K, V> ExactSizeIterator for IntoValues<K, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K, V> FusedIterator for IntoValues<K, V> {}

#[unstable(feature = "map_into_keys_values", issue = "55214")]
impl<K: Debug, V: Debug> fmt::Debug for IntoValues<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter()).finish()
}
}

#[stable(feature = "drain", since = "1.6.0")]
impl<'a, K, V> Iterator for Drain<'a, K, V> {
type Item = (K, V);
Expand Down