@@ -781,6 +781,130 @@ impl<T> Vec<T> {
781
781
}
782
782
}
783
783
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
+
784
908
/// Appends an element to the back of a collection.
785
909
///
786
910
/// # Panics
@@ -1155,90 +1279,9 @@ impl<T: PartialEq> Vec<T> {
1155
1279
/// assert_eq!(vec, [1, 2, 3, 2]);
1156
1280
/// ```
1157
1281
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1282
+ #[ inline]
1158
1283
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)
1242
1285
}
1243
1286
}
1244
1287
0 commit comments