Skip to content

Commit 5f732eb

Browse files
Rollup merge of #43041 - andersk:dedup_by, r=alexcrichton
Document unintuitive argument order for Vec::dedup_by relation When trying to use `dedup_by` to merge some auxiliary information from removed elements into kept elements, I was surprised to observe that `vec.dedup_by(same_bucket)` calls `same_bucket(a, b)` where `b` appears before `a` in the vector, and discards `a` when true is returned. This argument order is probably a bug, but since it has already been stabilized, I guess we should document it as a feature and move on. (`Vec::dedup` also uses `==` with this unexpected argument order, but I figure that’s not important since `==` is expected to be symmetric with no side effects.)
2 parents 2fdb9c9 + d68c3ab commit 5f732eb

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

src/liballoc/tests/vec.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ fn test_dedup_by() {
274274
vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
275275

276276
assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
277+
278+
let mut vec = vec![("foo", 1), ("foo", 2), ("bar", 3), ("bar", 4), ("bar", 5)];
279+
vec.dedup_by(|a, b| a.0 == b.0 && { b.1 += a.1; true });
280+
281+
assert_eq!(vec, [("foo", 3), ("bar", 12)]);
277282
}
278283

279284
#[test]

src/liballoc/vec.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,8 @@ impl<T> Vec<T> {
823823
}
824824
}
825825

826-
/// Removes consecutive elements in the vector that resolve to the same key.
826+
/// Removes all but the first of consecutive elements in the vector that resolve to the same
827+
/// key.
827828
///
828829
/// If the vector is sorted, this removes all duplicates.
829830
///
@@ -842,11 +843,13 @@ impl<T> Vec<T> {
842843
self.dedup_by(|a, b| key(a) == key(b))
843844
}
844845

845-
/// Removes consecutive elements in the vector according to a predicate.
846+
/// Removes all but the first of consecutive elements in the vector satisfying a given equality
847+
/// relation.
846848
///
847849
/// The `same_bucket` function is passed references to two elements from the vector, and
848-
/// returns `true` if the elements compare equal, or `false` if they do not. Only the first
849-
/// of adjacent equal items is kept.
850+
/// returns `true` if the elements compare equal, or `false` if they do not. The elements are
851+
/// passed in opposite order from their order in the vector, so if `same_bucket(a, b)` returns
852+
/// `true`, `a` is removed.
850853
///
851854
/// If the vector is sorted, this removes all duplicates.
852855
///

0 commit comments

Comments
 (0)