Skip to content

Commit

Permalink
Merge pull request #285 from cuviper/index-keys
Browse files Browse the repository at this point in the history
`impl Index<usize> for Keys`
  • Loading branch information
cuviper authored Jan 12, 2024
2 parents 84f772d + 555f6ea commit fda1ec4
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,10 @@ where

/// Access `IndexMap` values at indexed positions.
///
/// See [`Index<usize> for Keys`][keys] to access a map's keys instead.
///
/// [keys]: Keys#impl-Index<usize>-for-Keys<'a,+K,+V>
///
/// # Examples
///
/// ```
Expand Down
68 changes: 68 additions & 0 deletions src/map/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::{Bucket, Entries, IndexMap, Slice};
use alloc::vec::{self, Vec};
use core::fmt;
use core::iter::FusedIterator;
use core::ops::Index;
use core::slice;

impl<'a, K, V, S> IntoIterator for &'a IndexMap<K, V, S> {
Expand Down Expand Up @@ -326,6 +327,73 @@ impl<K, V> Default for Keys<'_, K, V> {
}
}

/// Access `IndexMap` keys at indexed positions.
///
/// While [`Index<usize> for IndexMap`][values] accesses a map's values,
/// indexing through [`IndexMap::keys`] offers an alternative to access a map's
/// keys instead.
///
/// [values]: IndexMap#impl-Index<usize>-for-IndexMap<K,+V,+S>
///
/// Since `Keys` is also an iterator, consuming items from the iterator will
/// offset the effective indexes. Similarly, if `Keys` is obtained from
/// [`Slice::keys`], indexes will be interpreted relative to the position of
/// that slice.
///
/// # Examples
///
/// ```
/// use indexmap::IndexMap;
///
/// let mut map = IndexMap::new();
/// for word in "Lorem ipsum dolor sit amet".split_whitespace() {
/// map.insert(word.to_lowercase(), word.to_uppercase());
/// }
///
/// assert_eq!(map[0], "LOREM");
/// assert_eq!(map.keys()[0], "lorem");
/// assert_eq!(map[1], "IPSUM");
/// assert_eq!(map.keys()[1], "ipsum");
///
/// map.reverse();
/// assert_eq!(map.keys()[0], "amet");
/// assert_eq!(map.keys()[1], "sit");
///
/// map.sort_keys();
/// assert_eq!(map.keys()[0], "amet");
/// assert_eq!(map.keys()[1], "dolor");
///
/// // Advancing the iterator will offset the indexing
/// let mut keys = map.keys();
/// assert_eq!(keys[0], "amet");
/// assert_eq!(keys.next().map(|s| &**s), Some("amet"));
/// assert_eq!(keys[0], "dolor");
/// assert_eq!(keys[1], "ipsum");
///
/// // Slices may have an offset as well
/// let slice = &map[2..];
/// assert_eq!(slice[0], "IPSUM");
/// assert_eq!(slice.keys()[0], "ipsum");
/// ```
///
/// ```should_panic
/// use indexmap::IndexMap;
///
/// let mut map = IndexMap::new();
/// map.insert("foo", 1);
/// println!("{:?}", map.keys()[10]); // panics!
/// ```
impl<'a, K, V> Index<usize> for Keys<'a, K, V> {
type Output = K;

/// Returns a reference to the key at the supplied `index`.
///
/// ***Panics*** if `index` is out of bounds.
fn index(&self, index: usize) -> &K {
&self.iter.as_slice()[index].key
}
}

/// An owning iterator over the keys of a `IndexMap`.
///
/// This `struct` is created by the [`into_keys`] method on [`IndexMap`].
Expand Down

0 comments on commit fda1ec4

Please sign in to comment.