@@ -781,6 +781,130 @@ impl<T> Vec<T> {
781781 }
782782 }
783783
784+ /// Removes consecutive elements in the vector that resolve to the same key.
785+ ///
786+ /// If the vector is sorted, this removes all duplicates.
787+ ///
788+ /// # Examples
789+ ///
790+ /// ```
791+ /// #![feature(dedup_by)]
792+ ///
793+ /// let mut vec = vec![10, 20, 21, 30, 20];
794+ ///
795+ /// vec.dedup_by_key(|i| *i / 10);
796+ ///
797+ /// assert_eq!(vec, [10, 20, 30, 20]);
798+ /// ```
799+ #[ unstable( feature = "dedup_by" , reason = "recently added" , issue = "37087" ) ]
800+ #[ inline]
801+ pub fn dedup_by_key < F , K > ( & mut self , mut key : F ) where F : FnMut ( & mut T ) -> K , K : PartialEq {
802+ self . dedup_by ( |a, b| key ( a) == key ( b) )
803+ }
804+
805+ /// Removes consecutive elements in the vector that resolve to the same key.
806+ ///
807+ /// If the vector is sorted, this removes all duplicates.
808+ ///
809+ /// # Examples
810+ ///
811+ /// ```
812+ /// #![feature(dedup_by)]
813+ /// use std::ascii::AsciiExt;
814+ ///
815+ /// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
816+ ///
817+ /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
818+ ///
819+ /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
820+ /// ```
821+ #[ unstable( feature = "dedup_by" , reason = "recently added" , issue = "37087" ) ]
822+ pub fn dedup_by < F > ( & mut self , mut same_bucket : F ) where F : FnMut ( & mut T , & mut T ) -> bool {
823+ unsafe {
824+ // Although we have a mutable reference to `self`, we cannot make
825+ // *arbitrary* changes. The `PartialEq` comparisons could panic, so we
826+ // must ensure that the vector is in a valid state at all time.
827+ //
828+ // The way that we handle this is by using swaps; we iterate
829+ // over all the elements, swapping as we go so that at the end
830+ // the elements we wish to keep are in the front, and those we
831+ // wish to reject are at the back. We can then truncate the
832+ // vector. This operation is still O(n).
833+ //
834+ // Example: We start in this state, where `r` represents "next
835+ // read" and `w` represents "next_write`.
836+ //
837+ // r
838+ // +---+---+---+---+---+---+
839+ // | 0 | 1 | 1 | 2 | 3 | 3 |
840+ // +---+---+---+---+---+---+
841+ // w
842+ //
843+ // Comparing self[r] against self[w-1], this is not a duplicate, so
844+ // we swap self[r] and self[w] (no effect as r==w) and then increment both
845+ // r and w, leaving us with:
846+ //
847+ // r
848+ // +---+---+---+---+---+---+
849+ // | 0 | 1 | 1 | 2 | 3 | 3 |
850+ // +---+---+---+---+---+---+
851+ // w
852+ //
853+ // Comparing self[r] against self[w-1], this value is a duplicate,
854+ // so we increment `r` but leave everything else unchanged:
855+ //
856+ // r
857+ // +---+---+---+---+---+---+
858+ // | 0 | 1 | 1 | 2 | 3 | 3 |
859+ // +---+---+---+---+---+---+
860+ // w
861+ //
862+ // Comparing self[r] against self[w-1], this is not a duplicate,
863+ // so swap self[r] and self[w] and advance r and w:
864+ //
865+ // r
866+ // +---+---+---+---+---+---+
867+ // | 0 | 1 | 2 | 1 | 3 | 3 |
868+ // +---+---+---+---+---+---+
869+ // w
870+ //
871+ // Not a duplicate, repeat:
872+ //
873+ // r
874+ // +---+---+---+---+---+---+
875+ // | 0 | 1 | 2 | 3 | 1 | 3 |
876+ // +---+---+---+---+---+---+
877+ // w
878+ //
879+ // Duplicate, advance r. End of vec. Truncate to w.
880+
881+ let ln = self . len ( ) ;
882+ if ln <= 1 {
883+ return ;
884+ }
885+
886+ // Avoid bounds checks by using raw pointers.
887+ let p = self . as_mut_ptr ( ) ;
888+ let mut r: usize = 1 ;
889+ let mut w: usize = 1 ;
890+
891+ while r < ln {
892+ let p_r = p. offset ( r as isize ) ;
893+ let p_wm1 = p. offset ( ( w - 1 ) as isize ) ;
894+ if !same_bucket ( & mut * p_r, & mut * p_wm1) {
895+ if r != w {
896+ let p_w = p_wm1. offset ( 1 ) ;
897+ mem:: swap ( & mut * p_r, & mut * p_w) ;
898+ }
899+ w += 1 ;
900+ }
901+ r += 1 ;
902+ }
903+
904+ self . truncate ( w) ;
905+ }
906+ }
907+
784908 /// Appends an element to the back of a collection.
785909 ///
786910 /// # Panics
@@ -1155,90 +1279,9 @@ impl<T: PartialEq> Vec<T> {
11551279 /// assert_eq!(vec, [1, 2, 3, 2]);
11561280 /// ```
11571281 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1282+ #[ inline]
11581283 pub fn dedup ( & mut self ) {
1159- unsafe {
1160- // Although we have a mutable reference to `self`, we cannot make
1161- // *arbitrary* changes. The `PartialEq` comparisons could panic, so we
1162- // must ensure that the vector is in a valid state at all time.
1163- //
1164- // The way that we handle this is by using swaps; we iterate
1165- // over all the elements, swapping as we go so that at the end
1166- // the elements we wish to keep are in the front, and those we
1167- // wish to reject are at the back. We can then truncate the
1168- // vector. This operation is still O(n).
1169- //
1170- // Example: We start in this state, where `r` represents "next
1171- // read" and `w` represents "next_write`.
1172- //
1173- // r
1174- // +---+---+---+---+---+---+
1175- // | 0 | 1 | 1 | 2 | 3 | 3 |
1176- // +---+---+---+---+---+---+
1177- // w
1178- //
1179- // Comparing self[r] against self[w-1], this is not a duplicate, so
1180- // we swap self[r] and self[w] (no effect as r==w) and then increment both
1181- // r and w, leaving us with:
1182- //
1183- // r
1184- // +---+---+---+---+---+---+
1185- // | 0 | 1 | 1 | 2 | 3 | 3 |
1186- // +---+---+---+---+---+---+
1187- // w
1188- //
1189- // Comparing self[r] against self[w-1], this value is a duplicate,
1190- // so we increment `r` but leave everything else unchanged:
1191- //
1192- // r
1193- // +---+---+---+---+---+---+
1194- // | 0 | 1 | 1 | 2 | 3 | 3 |
1195- // +---+---+---+---+---+---+
1196- // w
1197- //
1198- // Comparing self[r] against self[w-1], this is not a duplicate,
1199- // so swap self[r] and self[w] and advance r and w:
1200- //
1201- // r
1202- // +---+---+---+---+---+---+
1203- // | 0 | 1 | 2 | 1 | 3 | 3 |
1204- // +---+---+---+---+---+---+
1205- // w
1206- //
1207- // Not a duplicate, repeat:
1208- //
1209- // r
1210- // +---+---+---+---+---+---+
1211- // | 0 | 1 | 2 | 3 | 1 | 3 |
1212- // +---+---+---+---+---+---+
1213- // w
1214- //
1215- // Duplicate, advance r. End of vec. Truncate to w.
1216-
1217- let ln = self . len ( ) ;
1218- if ln <= 1 {
1219- return ;
1220- }
1221-
1222- // Avoid bounds checks by using raw pointers.
1223- let p = self . as_mut_ptr ( ) ;
1224- let mut r: usize = 1 ;
1225- let mut w: usize = 1 ;
1226-
1227- while r < ln {
1228- let p_r = p. offset ( r as isize ) ;
1229- let p_wm1 = p. offset ( ( w - 1 ) as isize ) ;
1230- if * p_r != * p_wm1 {
1231- if r != w {
1232- let p_w = p_wm1. offset ( 1 ) ;
1233- mem:: swap ( & mut * p_r, & mut * p_w) ;
1234- }
1235- w += 1 ;
1236- }
1237- r += 1 ;
1238- }
1239-
1240- self . truncate ( w) ;
1241- }
1284+ self . dedup_by ( |a, b| a == b)
12421285 }
12431286}
12441287
0 commit comments