/// assert_eq!(vec, [1, 2, 3, 2]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
pub fn dedup(&mut self) {
+ self.dedup_by(|a, b| a == b)
+ }
+}
+
+impl<T> Vec<T> {
+ /// Removes consecutive elements in the vector that resolve to the same key.
+ ///
+ /// If the vector is sorted, this removes all duplicates.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(dedup_by)]
+ ///
+ /// let mut vec = vec![10, 20, 21, 30, 20];
+ ///
+ /// vec.dedup_by_key(|i| *i / 10);
+ ///
+ /// assert_eq!(vec, [10, 20, 30, 20]);
+ /// ```
+ #[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
+ #[inline]
+ pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq {
+ self.dedup_by(|a, b| key(a) == key(b))
+ }
+
+ /// Removes consecutive elements in the vector that resolve to the same key.
+ ///
+ /// If the vector is sorted, this removes all duplicates.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(dedup_by)]
+ /// use std::ascii::AsciiExt;
+ ///
+ /// 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"]);
+ /// ```
+ #[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
+ pub fn dedup_by<F>(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
unsafe {
// Although we have a mutable reference to `self`, we cannot make
// *arbitrary* changes. The `PartialEq` comparisons could panic, so we
while r < ln {
let p_r = p.offset(r as isize);
let p_wm1 = p.offset((w - 1) as isize);
- if *p_r != *p_wm1 {
+ if !same_bucket(&mut *p_r, &mut *p_wm1) {
if r != w {
let p_w = p_wm1.offset(1);
mem::swap(&mut *p_r, &mut *p_w);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::iter::{FromIterator, repeat};
use std::mem::size_of;
case(vec![1, 1, 2, 2, 2, 3, 3], vec![1, 2, 3]);
}
+#[test]
+fn test_dedup_by_key() {
+ fn case(a: Vec<i32>, b: Vec<i32>) {
+ let mut v = a;
+ v.dedup_by_key(|i| *i / 10);
+ assert_eq!(v, b);
+ }
+ case(vec![], vec![]);
+ case(vec![10], vec![10]);
+ case(vec![10, 11], vec![10]);
+ case(vec![10, 20, 30], vec![10, 20, 30]);
+ case(vec![10, 11, 20, 30], vec![10, 20, 30]);
+ case(vec![10, 20, 21, 30], vec![10, 20, 30]);
+ case(vec![10, 20, 30, 31], vec![10, 20, 30]);
+ case(vec![10, 11, 20, 21, 22, 30, 31], vec![10, 20, 30]);
+}
+
+#[test]
+fn test_dedup_by() {
+ 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"]);
+}
+
#[test]
fn test_dedup_unique() {
let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];