Proposal: Add a .pick(val) Method to Collection Types
Hello Rust community,
I'd like to propose (or at least start a conversation around) the addition of a .pick(val) method to standard collection types like Vec<T>, HashSet<T>, and HashMap<K, V>.
What .pick(val) Would Do
This method would search for a given value (or key), and:
Return it if found
Panic if not found
Example (on Vec<T>):
let nums = vec![1, 2, 3];
let x = nums.pick(2); // returns 2
let y = nums.pick(4); // panics: "Value not found in vector!"
This is conceptually similar to Option::expect(), but applied to containers.
Why This Might Be Useful
Improves ergonomics for common lookup patterns
Encourages clear “must-be-present” semantics
Reduces boilerplate like .iter().find(...).expect(...)
Aligns with similar patterns in other major languages (Python, JS, Ruby, etc.)
Candidate Data Structures
The .pick(val) method (or trait) could apply to:
Vec<T>
HashSet<T>
HashMap<K, V>
BTreeMap<K, V>
Possibly LinkedList<T>, IndexMap, etc.
Considerations
Of course, this should be used with care in production (like any panic-based function), and an idiomatic .try_pick(val) returning Option<T> might also be worth discussing.
What is the purpose of returning a value you must already have? I can see one particular use for this operation, interning, but that is not a common operation, and when it is used, you need the “insert if not found” part too.
Can you explain this further and give examples of situations where this is desired? Of course, sometimes it makes sense to assert that a collection contains an element, but why do it exactly this way?
My understanding is that it is an intentional design decision that Vec/slices largely don’t contain methods that do linear searches; you have to write .iter() to make it clear that you are using a potentially costly linear operation.
Also, it’s not good practice to have a panicking search operation like this; panics should either
be performed in the calling code so that the panic message can be customized to the situation, or
be a consequence of a likely bug (e.g. out-of-bounds indexing).
Can you give examples of the same operation in Python and JS? I’m not aware of either one having a dedicated function for finding and returning the same value you put in.
Types that have heterogeneous PartialEq impl(s) would probably be the most common use case, but also types with a custom Eq that only compares a subset of the fields. That said, I agree that a method like this wouldn't be a good fit for Rust.
Maybe instead of Vec::pick we could have a function like this?
impl<T: PartialEq> Vec<T> {
/// Returns the number of items present in the `Vec` equivalent to `item`
fn number_of(&self, item: T) -> usize {
// snip
}
}
Hardly seems worth it. v.number_of(p) can already be written v.into_iter().filter(p).count(), which is fine -- and more general since you can also use .iter() with a fn(&T) -> bool and such, rather than always consuming.
(Indeed, the Filter iterator type overrides the count method to do that efficiently, too.)