@@ -782,6 +782,130 @@ impl<T> Vec<T> {
782
782
}
783
783
}
784
784
785
+ /// Removes consecutive elements in the vector that resolve to the same key.
786
+ ///
787
+ /// If the vector is sorted, this removes all duplicates.
788
+ ///
789
+ /// # Examples
790
+ ///
791
+ /// ```
792
+ /// #![feature(dedup_by)]
793
+ ///
794
+ /// let mut vec = vec![10, 20, 21, 30, 20];
795
+ ///
796
+ /// vec.dedup_by_key(|i| *i / 10);
797
+ ///
798
+ /// assert_eq!(vec, [10, 20, 30, 20]);
799
+ /// ```
800
+ #[ unstable( feature = "dedup_by" , reason = "recently added" , issue = "37087" ) ]
801
+ #[ inline]
802
+ pub fn dedup_by_key < F , K > ( & mut self , mut key : F ) where F : FnMut ( & mut T ) -> K , K : PartialEq {
803
+ self . dedup_by ( |a, b| key ( a) == key ( b) )
804
+ }
805
+
806
+ /// Removes consecutive elements in the vector that resolve to the same key.
807
+ ///
808
+ /// If the vector is sorted, this removes all duplicates.
809
+ ///
810
+ /// # Examples
811
+ ///
812
+ /// ```
813
+ /// #![feature(dedup_by)]
814
+ /// use std::ascii::AsciiExt;
815
+ ///
816
+ /// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
817
+ ///
818
+ /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
819
+ ///
820
+ /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
821
+ /// ```
822
+ #[ unstable( feature = "dedup_by" , reason = "recently added" , issue = "37087" ) ]
823
+ pub fn dedup_by < F > ( & mut self , mut same_bucket : F ) where F : FnMut ( & mut T , & mut T ) -> bool {
824
+ unsafe {
825
+ // Although we have a mutable reference to `self`, we cannot make
826
+ // *arbitrary* changes. The `PartialEq` comparisons could panic, so we
827
+ // must ensure that the vector is in a valid state at all time.
828
+ //
829
+ // The way that we handle this is by using swaps; we iterate
830
+ // over all the elements, swapping as we go so that at the end
831
+ // the elements we wish to keep are in the front, and those we
832
+ // wish to reject are at the back. We can then truncate the
833
+ // vector. This operation is still O(n).
834
+ //
835
+ // Example: We start in this state, where `r` represents "next
836
+ // read" and `w` represents "next_write`.
837
+ //
838
+ // r
839
+ // +---+---+---+---+---+---+
840
+ // | 0 | 1 | 1 | 2 | 3 | 3 |
841
+ // +---+---+---+---+---+---+
842
+ // w
843
+ //
844
+ // Comparing self[r] against self[w-1], this is not a duplicate, so
845
+ // we swap self[r] and self[w] (no effect as r==w) and then increment both
846
+ // r and w, leaving us with:
847
+ //
848
+ // r
849
+ // +---+---+---+---+---+---+
850
+ // | 0 | 1 | 1 | 2 | 3 | 3 |
851
+ // +---+---+---+---+---+---+
852
+ // w
853
+ //
854
+ // Comparing self[r] against self[w-1], this value is a duplicate,
855
+ // so we increment `r` but leave everything else unchanged:
856
+ //
857
+ // r
858
+ // +---+---+---+---+---+---+
859
+ // | 0 | 1 | 1 | 2 | 3 | 3 |
860
+ // +---+---+---+---+---+---+
861
+ // w
862
+ //
863
+ // Comparing self[r] against self[w-1], this is not a duplicate,
864
+ // so swap self[r] and self[w] and advance r and w:
865
+ //
866
+ // r
867
+ // +---+---+---+---+---+---+
868
+ // | 0 | 1 | 2 | 1 | 3 | 3 |
869
+ // +---+---+---+---+---+---+
870
+ // w
871
+ //
872
+ // Not a duplicate, repeat:
873
+ //
874
+ // r
875
+ // +---+---+---+---+---+---+
876
+ // | 0 | 1 | 2 | 3 | 1 | 3 |
877
+ // +---+---+---+---+---+---+
878
+ // w
879
+ //
880
+ // Duplicate, advance r. End of vec. Truncate to w.
881
+
882
+ let ln = self . len ( ) ;
883
+ if ln <= 1 {
884
+ return ;
885
+ }
886
+
887
+ // Avoid bounds checks by using raw pointers.
888
+ let p = self . as_mut_ptr ( ) ;
889
+ let mut r: usize = 1 ;
890
+ let mut w: usize = 1 ;
891
+
892
+ while r < ln {
893
+ let p_r = p. offset ( r as isize ) ;
894
+ let p_wm1 = p. offset ( ( w - 1 ) as isize ) ;
895
+ if !same_bucket ( & mut * p_r, & mut * p_wm1) {
896
+ if r != w {
897
+ let p_w = p_wm1. offset ( 1 ) ;
898
+ mem:: swap ( & mut * p_r, & mut * p_w) ;
899
+ }
900
+ w += 1 ;
901
+ }
902
+ r += 1 ;
903
+ }
904
+
905
+ self . truncate ( w) ;
906
+ }
907
+ }
908
+
785
909
/// Appends an element to the back of a collection.
786
910
///
787
911
/// # Panics
@@ -1162,132 +1286,6 @@ impl<T: PartialEq> Vec<T> {
1162
1286
}
1163
1287
}
1164
1288
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 {
1205
- unsafe {
1206
- // Although we have a mutable reference to `self`, we cannot make
1207
- // *arbitrary* changes. The `PartialEq` comparisons could panic, so we
1208
- // must ensure that the vector is in a valid state at all time.
1209
- //
1210
- // The way that we handle this is by using swaps; we iterate
1211
- // over all the elements, swapping as we go so that at the end
1212
- // the elements we wish to keep are in the front, and those we
1213
- // wish to reject are at the back. We can then truncate the
1214
- // vector. This operation is still O(n).
1215
- //
1216
- // Example: We start in this state, where `r` represents "next
1217
- // read" and `w` represents "next_write`.
1218
- //
1219
- // r
1220
- // +---+---+---+---+---+---+
1221
- // | 0 | 1 | 1 | 2 | 3 | 3 |
1222
- // +---+---+---+---+---+---+
1223
- // w
1224
- //
1225
- // Comparing self[r] against self[w-1], this is not a duplicate, so
1226
- // we swap self[r] and self[w] (no effect as r==w) and then increment both
1227
- // r and w, leaving us with:
1228
- //
1229
- // r
1230
- // +---+---+---+---+---+---+
1231
- // | 0 | 1 | 1 | 2 | 3 | 3 |
1232
- // +---+---+---+---+---+---+
1233
- // w
1234
- //
1235
- // Comparing self[r] against self[w-1], this value is a duplicate,
1236
- // so we increment `r` but leave everything else unchanged:
1237
- //
1238
- // r
1239
- // +---+---+---+---+---+---+
1240
- // | 0 | 1 | 1 | 2 | 3 | 3 |
1241
- // +---+---+---+---+---+---+
1242
- // w
1243
- //
1244
- // Comparing self[r] against self[w-1], this is not a duplicate,
1245
- // so swap self[r] and self[w] and advance r and w:
1246
- //
1247
- // r
1248
- // +---+---+---+---+---+---+
1249
- // | 0 | 1 | 2 | 1 | 3 | 3 |
1250
- // +---+---+---+---+---+---+
1251
- // w
1252
- //
1253
- // Not a duplicate, repeat:
1254
- //
1255
- // r
1256
- // +---+---+---+---+---+---+
1257
- // | 0 | 1 | 2 | 3 | 1 | 3 |
1258
- // +---+---+---+---+---+---+
1259
- // w
1260
- //
1261
- // Duplicate, advance r. End of vec. Truncate to w.
1262
-
1263
- let ln = self . len ( ) ;
1264
- if ln <= 1 {
1265
- return ;
1266
- }
1267
-
1268
- // Avoid bounds checks by using raw pointers.
1269
- let p = self . as_mut_ptr ( ) ;
1270
- let mut r: usize = 1 ;
1271
- let mut w: usize = 1 ;
1272
-
1273
- while r < ln {
1274
- let p_r = p. offset ( r as isize ) ;
1275
- let p_wm1 = p. offset ( ( w - 1 ) as isize ) ;
1276
- if !same_bucket ( & mut * p_r, & mut * p_wm1) {
1277
- if r != w {
1278
- let p_w = p_wm1. offset ( 1 ) ;
1279
- mem:: swap ( & mut * p_r, & mut * p_w) ;
1280
- }
1281
- w += 1 ;
1282
- }
1283
- r += 1 ;
1284
- }
1285
-
1286
- self . truncate ( w) ;
1287
- }
1288
- }
1289
- }
1290
-
1291
1289
////////////////////////////////////////////////////////////////////////////////
1292
1290
// Internal methods and functions
1293
1291
////////////////////////////////////////////////////////////////////////////////
0 commit comments