Skip to content

Commit be34bac

Browse files
committed
Add Vec::dedup_by and Vec::dedup_by_key
1 parent f14f4db commit be34bac

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

src/libcollections/vec.rs

+46-1
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,52 @@ impl<T: PartialEq> Vec<T> {
11561156
/// assert_eq!(vec, [1, 2, 3, 2]);
11571157
/// ```
11581158
#[stable(feature = "rust1", since = "1.0.0")]
1159+
#[inline]
11591160
pub fn dedup(&mut self) {
1161+
self.dedup_by(|a, b| a == b)
1162+
}
1163+
}
1164+
1165+
impl<T> Vec<T> {
1166+
/// Removes consecutive elements in the vector that resolve to the same key.
1167+
///
1168+
/// If the vector is sorted, this removes all duplicates.
1169+
///
1170+
/// # Examples
1171+
///
1172+
/// ```
1173+
/// #![feature(dedup_by)]
1174+
///
1175+
/// let mut vec = vec![10, 20, 21, 30, 20];
1176+
///
1177+
/// vec.dedup_by_key(|i| *i / 10);
1178+
///
1179+
/// assert_eq!(vec, [10, 20, 30, 20]);
1180+
/// ```
1181+
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
1182+
#[inline]
1183+
pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq {
1184+
self.dedup_by(|a, b| key(a) == key(b))
1185+
}
1186+
1187+
/// Removes consecutive elements in the vector that resolve to the same key.
1188+
///
1189+
/// If the vector is sorted, this removes all duplicates.
1190+
///
1191+
/// # Examples
1192+
///
1193+
/// ```
1194+
/// #![feature(dedup_by)]
1195+
/// use std::ascii::AsciiExt;
1196+
///
1197+
/// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
1198+
///
1199+
/// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1200+
///
1201+
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
1202+
/// ```
1203+
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
1204+
pub fn dedup_by<F>(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
11601205
unsafe {
11611206
// Although we have a mutable reference to `self`, we cannot make
11621207
// *arbitrary* changes. The `PartialEq` comparisons could panic, so we
@@ -1228,7 +1273,7 @@ impl<T: PartialEq> Vec<T> {
12281273
while r < ln {
12291274
let p_r = p.offset(r as isize);
12301275
let p_wm1 = p.offset((w - 1) as isize);
1231-
if *p_r != *p_wm1 {
1276+
if !same_bucket(&mut *p_r, &mut *p_wm1) {
12321277
if r != w {
12331278
let p_w = p_wm1.offset(1);
12341279
mem::swap(&mut *p_r, &mut *p_w);

src/libcollectionstest/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#![feature(collections)]
1717
#![feature(collections_bound)]
1818
#![feature(const_fn)]
19+
#![feature(dedup_by)]
1920
#![feature(enumset)]
2021
#![feature(pattern)]
2122
#![feature(rand)]

src/libcollectionstest/vec.rs

+26
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::ascii::AsciiExt;
1112
use std::borrow::Cow;
1213
use std::iter::{FromIterator, repeat};
1314
use std::mem::size_of;
@@ -230,6 +231,31 @@ fn test_dedup() {
230231
case(vec![1, 1, 2, 2, 2, 3, 3], vec![1, 2, 3]);
231232
}
232233

234+
#[test]
235+
fn test_dedup_by_key() {
236+
fn case(a: Vec<i32>, b: Vec<i32>) {
237+
let mut v = a;
238+
v.dedup_by_key(|i| *i / 10);
239+
assert_eq!(v, b);
240+
}
241+
case(vec![], vec![]);
242+
case(vec![10], vec![10]);
243+
case(vec![10, 11], vec![10]);
244+
case(vec![10, 20, 30], vec![10, 20, 30]);
245+
case(vec![10, 11, 20, 30], vec![10, 20, 30]);
246+
case(vec![10, 20, 21, 30], vec![10, 20, 30]);
247+
case(vec![10, 20, 30, 31], vec![10, 20, 30]);
248+
case(vec![10, 11, 20, 21, 22, 30, 31], vec![10, 20, 30]);
249+
}
250+
251+
#[test]
252+
fn test_dedup_by() {
253+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
254+
vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
255+
256+
assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
257+
}
258+
233259
#[test]
234260
fn test_dedup_unique() {
235261
let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];

0 commit comments

Comments
 (0)