@@ -8,53 +8,56 @@ This library aims to be a good alternative to all comprehension libraries,
88for the libraries you encounter when searching "comprehension" on crate.io,
99we have already done:
1010Fully covered libraries:
11- * [ comprehension] ( https://crates.io/crates/comprehension )
12- * [ kt-list-comprehensions] ( https://crates.io/crates/kt-list-comprehensions )
13- * [ iter-comprehensions] ( https://crates.io/crates/iter-comprehensions )
14- * [ cute] ( https://crates.io/crates/cute )
11+ * [ comprehension] ( https://crates.io/crates/comprehension )
12+ * [ kt-list-comprehensions] ( https://crates.io/crates/kt-list-comprehensions )
13+ * [ iter-comprehensions] ( https://crates.io/crates/iter-comprehensions )
14+ * [ cute] ( https://crates.io/crates/cute )
1515
1616Partially covered libraries:
1717* [ list_comprehension_macro] ( https://crates.io/crates/list_comprehension_macro )
18- * Does not provide a unified macro that distinguishes by mapping expression (like real Python comprehensions)
18+ * Does not provide a unified macro that distinguishes by mapping expression (like real Python comprehensions)
19+
1920 (No plans to support this, as this library already provides all collection types in the Rust standard library)
2021
21- * Does not support while loop
22+ * Does not support while loop
2223
2324* [ list_comprehension] ( https://crates.io/crates/list_comprehension )
24- * Does not support let-else variable binding
25- (No plans to support this, as it overly complicates the for-in part, and these things can be completely solved in the mapping return block)
25+ * Does not support let-else variable binding
2626
27- # Usage
27+ (No plans to support this, as it overly complicates the for-in part, and these things can be completely solved in the mapping return block)
2828
29- ## Collection Comprehensions
29+ # Collection Comprehensions
3030
3131You can completely treat collection comprehension macros as sugar for ` for loop `
3232(In fact, these macros are implemented using ` for loop ` )
3333So you'll see many familiar syntaxes
3434However, they will be more ergonomic and easier to read and use
3535
36- ### Simple Example
36+ # Simple Example
3737``` rust
3838use better_comprehension :: vector;
3939let vec_1 = vec! [" AB" . to_string (), " CD" . to_string ()];
4040let vec_2 = vec! [" 12" . to_string (), " 34" . to_string ()];
4141
4242
43- // Ownership consuming iteration (just pass the single identifier)
43+ // Ownership consuming iteration
44+ // (just pass the single identifier)
4445// x's type is &String
4546let vec : Vec <String > = vector! [x . clone () for x in vec_1 ];
4647// println!("{:?}", vec_1); // borrow of moved value
4748assert_eq! (vec , vec! [" AB" . to_string (), " CD" . to_string ()]);
4849
49- // Ownership preserving iteration (pass &collection or collection.iter().other_method())
50+ // Ownership preserving iteration
51+ // (pass &collection or collection.iter().other_method())
5052// x's type is &String
5153let vec : Vec <String > = vector! [x . clone () for x in vec_2 . iter ()];
52- // let vec: Vec<String> = vector![x.clone() for x in &vec_2]; // equivalent writing
54+ // equivalent writing
55+ // let vec: Vec<String> = vector![x.clone() for x in &vec_2];
5356println! (" {:?}" , vec_2 ); // vec_2 is alive
5457assert_eq! (vec , vec! [" 12" . to_string (), " 34" . to_string ()]);
5558```
5659
57- ### if in collection
60+ # if in comprehension
5861
5962` for ` pattern ` in ` collection ` if ` ... will be translated to
6063``` rust
@@ -65,14 +68,17 @@ for pattern in collection {
6568}
6669```
6770
68- #### if conditions as filtering conditions
71+ ## if conditions as filtering conditions
6972Where conditions is any expression that returns a bool
7073Only when the expression returns true, it will be mapped
7174``` rust
7275use better_comprehension :: linked_list;
7376use std :: collections :: LinkedList ;
7477// i's type is i32
75- let linked_list = linked_list! [ i * 2 for i in 1 ..= 3 if i != 2 ];
78+ let linked_list = linked_list! [
79+ i * 2
80+ for i in 1 ..= 3 if i != 2
81+ ];
7682assert_eq! (linked_list , LinkedList :: from ([2 , 6 ]));
7783```
7884
@@ -81,22 +87,29 @@ use better_comprehension::linked_list;
8187use std :: collections :: LinkedList ;
8288let judge_function = | i : i32 | i != 2 ;
8389// i's type is i32
84- let linked_list = linked_list! [ i * 2 for i in 1 ..= 3 if judge_function (i ) ];
90+ let linked_list = linked_list! [
91+ i * 2
92+ for i in 1 ..= 3 if judge_function (i )
93+ ];
8594assert_eq! (linked_list , LinkedList :: from ([2 , 6 ]));
8695```
8796
88- #### if let expression
97+ ## if let expression
8998``` rust
9099use better_comprehension :: vector;
91- let vec_1 = vec! [Some (" 123" . to_string ()), None , Some (" 456" . to_string ())];
100+ let vec_1 = vec! [Some (" 123" . to_string ()),
101+ None ,
102+ Some (" 456" . to_string ())];
92103let vec = vector! [
93104 __x__ . clone ()
94105 for x in vec_1 if let Some (__x__ ) = x
95106];
96- assert_eq! (vec , vec! [" 123" . to_string (), " 456" . to_string ()]);
107+ assert_eq! (vec , vec! [" 123" . to_string (),
108+ " 456" . to_string ()]
109+ );
97110```
98111
99- #### Return different values based on conditions
112+ # Return different values based on conditions
100113``` rust
101114use better_comprehension :: b_tree_set;
102115use std :: collections :: BTreeSet ;
@@ -107,7 +120,7 @@ let b_tree_set = b_tree_set!{
107120assert_eq! (b_tree_set , BTreeSet :: from ([1 , 13 ]));
108121```
109122
110- ### Use pattern matching
123+ # Use pattern matching
111124``` rust
112125use better_comprehension :: vec_deque;
113126use std :: collections :: VecDeque ;
@@ -118,7 +131,7 @@ struct Person {
118131}
119132
120133let people = [Person { name : " Joe" . to_string (), age : 20 },
121- Person { name : " Bob" . to_string (), age : 25 }];
134+ Person { name : " Bob" . to_string (), age : 25 }];
122135
123136// name's type is &String
124137let vec_deque : VecDeque <String > = vec_deque! [
@@ -130,7 +143,7 @@ println!("{:?}", people); // people is alive
130143assert_eq! (vec_deque , VecDeque :: from ([" Bob" . to_string ()]));
131144```
132145
133- ### Nested Comprehensions
146+ # Nested Comprehensions
134147Like Python's comprehensions, this library's for loop is read from top to bottom.
135148
136149``` rust
@@ -151,10 +164,10 @@ let vec = vector![
151164 for top in 1 ..= 3 if top != 2
152165 for bottom in 4 ..= 6 if bottom + top != 4 ];
153166assert_eq! (vec , vec! [(1 , 4 ), (1 , 5 ), (1 , 6 ),
154- (3 , 4 ), (3 , 5 ), (3 , 6 )]);
167+ (3 , 4 ), (3 , 5 ), (3 , 6 )]);
155168```
156169
157- ### Execute code in block before returning
170+ # Execute code in block before returning
158171This is a very powerful feature, you can execute any code before returning but it will reduce readability, please use it with caution
159172``` rust
160173use better_comprehension :: vector;
@@ -185,7 +198,7 @@ assert_eq!(
185198);
186199```
187200
188- ### description of ergonomic
201+ # description of ergonomic
189202Please note, in Rust, for loop consumes ownership.
190203So usually, for multi-layer loops, if you want the original collection to be consumed, you should write it like this:
191204``` rust
@@ -228,6 +241,7 @@ In this library, you don't need to do this, the macros will automatically handle
228241You only need to do two things:
2292421 . For the collection you want to keep ownership, add ` .iter() ` or use ` & `
2302432 . Directly pass the variable name of the collection you want to consume
244+
231245The rest will be automatically handled in the macro.
232246``` rust
233247use better_comprehension :: vector;
@@ -246,7 +260,7 @@ println!("{:?}", vec_2); // work well
246260// println!("{:?}", vec_3); // borrow of moved value
247261```
248262
249- ### Key-value collection types
263+ # Key-value collection types
250264Also, this library supports key-value collection types, HashMap, BTreeMap
251265And supports three key-value separators "=>" ":" ","
252266
@@ -280,7 +294,7 @@ assert_eq!(
280294);
281295```
282296
283- ### Some details
297+ # Some details
284298vector! : push() to add elements
285299
286300binary_heap! : push() to add elements
@@ -297,7 +311,7 @@ b_tree_map! : insert() to add key-value pairs
297311
298312b_tree_set! : insert() to add elements
299313
300- ## Iterator Comprehensions
314+ # Iterator Comprehensions
301315This library also supports iterator comprehensions, but as the author, I do not recommend using them, the reasons are as follows:
3023161 . In the collection comprehension, we also use references to derive, as long as we do not consume the original collection, we can achieve the same thing
3033172 . The cost of getting a reference copy is not large
@@ -311,11 +325,11 @@ However, to ensure the correctness of the iterator comprehension, only two itera
311325``` rust
312326use better_comprehension :: iterator_ref;
313327let vec_1 = [" 123" . to_string (),
314- " 456" . to_string (),
315- " 789" . to_string ()];
328+ " 456" . to_string (),
329+ " 789" . to_string ()];
316330let vec_2 = [" ABC" . to_string (),
317- " DEF" . to_string (),
318- " GHI" . to_string ()];
331+ " DEF" . to_string (),
332+ " GHI" . to_string ()];
319333
320334let mut result3 = iterator_ref! [
321335 (x . clone (), y . clone ()) if x . contains (" 1" ) else (y . clone (), x . clone ())
@@ -347,11 +361,11 @@ None
347361The above writing is equivalent to the following writing
348362``` rust
349363let vec_1 = [" 123" . to_string (),
350- " 456" . to_string (),
351- " 789" . to_string ()];
364+ " 456" . to_string (),
365+ " 789" . to_string ()];
352366let vec_2 = [" ABC" . to_string (),
353- " DEF" . to_string (),
354- " GHI" . to_string ()];
367+ " DEF" . to_string (),
368+ " GHI" . to_string ()];
355369
356370let mut result3 = {
357371 let vec_2 = vec_2 . iter (). collect :: <Vec <_ >>();
@@ -385,14 +399,14 @@ This implementation makes the following features in collection comprehension una
385399
386400# Differences
387401* Ownership consumption:
388- * Collection comprehension:
402+ * Collection comprehension:
389403 * Using & or .iter() does not consume ownership
390404 * Directly passing the variable name consumes ownership
391- * Iterator comprehension:
405+ * Iterator comprehension:
392406 * Always does not consume ownership, but only allows passing in a single identifier and range expression that does not follow any method calls
393407
394408* Differences in features:
395- * if let expression
409+ * if let expression
396410 * Collection comprehension: supported
397411 * Iterator comprehension: not supported
398412
@@ -420,8 +434,8 @@ assert_eq!(matrix, vec![vec![1, 2, 3],
420434assert_eq! (
421435 transposed ,
422436 vec! [vec! [1 , 4 , 7 ],
423- vec! [2 , 5 , 8 ],
424- vec! [3 , 6 , 9 ]]
437+ vec! [2 , 5 , 8 ],
438+ vec! [3 , 6 , 9 ]]
425439);
426440```
427441
@@ -495,7 +509,7 @@ let math_scores: HashMap<&String, u8> = hash_map![
495509assert_eq! (
496510 math_scores ,
497511 HashMap :: from ([(& " Alice" . to_string (), 95 ),
498- (& " Bob" . to_string (), 78 )]));
512+ (& " Bob" . to_string (), 78 )]));
499513
500514// use for loop
501515let high_scores = {
0 commit comments