Skip to content

Confusing reverse order in dedup_by docs #157959

Description

@m4dh0rs3

Location (URL)

/// Removes all but the first of consecutive elements in the vector satisfying a given equality
/// relation.
///
/// The `same_bucket` function is passed references to two elements from the vector and
/// must determine if the elements compare equal. The elements are passed in opposite order
/// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.
///
/// If the vector is sorted, this removes all duplicates.
///
/// # Examples
///
/// ```
/// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
///
/// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
///
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
/// ```
#[stable(feature = "dedup_by", since = "1.16.0")]
pub fn dedup_by<F>(&mut self, mut same_bucket: F)
where
F: FnMut(&mut T, &mut T) -> bool,
{

Summary

The docs say "all but the first" consecutive equal elements are removed. Equality is given by passing a same_bucket function. The docs continue, "if same_bucket(a, b) returns true, a is removed."

The catch here is that same_bucket receives a, b in the opposite order from the slice.

The docs are correct, but unnecessarily complicated. Changing the implementation to follow the actual order of the slice would break a lot of code. But the docs could just say "Removes all but the last of consecutive equal elements" and remove the reversed-order stuff from the docs.

(Side-note: The docs speak of same_bucket as a "equality relation", which had me wonder, before I found my bug, whether same_bucket needs to be an equivalence relation. But that is not necessary at all. Maybe remove that part too.)

Metadata

Metadata

Assignees

Labels

A-docsArea: Documentation for any part of the project, including the compiler, standard library, and tools

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions