lowdash/
reverse.rs

1/// Reverse a collection, returning a new vector with the elements in reverse order.
2///
3/// This function takes a slice of items and returns a new `Vec<T>` containing all the elements
4/// from the input collection in reverse order.
5///
6/// **Time Complexity:**  
7/// O(n), where n is the number of elements in the collection.
8///
9/// # Arguments
10///
11/// * `collection` - A slice of items to be reversed.
12///
13/// # Type Parameters
14///
15/// * `T` - The type of elements in the collection. Must implement `Clone`.
16///
17/// # Returns
18///
19/// * `Vec<T>` - A new vector containing all elements from the input collection in reverse order.
20///
21/// # Examples
22///
23/// ```rust
24/// use lowdash::reverse;
25///
26/// let numbers = vec![1, 2, 3, 4, 5];
27/// let reversed = reverse(&numbers);
28/// assert_eq!(reversed, vec![5, 4, 3, 2, 1]);
29/// ```
30///
31/// ```rust
32/// use lowdash::reverse;
33///
34/// #[derive(Debug, PartialEq, Clone)]
35/// struct Person {
36///     name: String,
37///     age: u32,
38/// }
39///
40/// let people = vec![
41///     Person { name: "Alice".to_string(), age: 25 },
42///     Person { name: "Bob".to_string(), age: 30 },
43///     Person { name: "Carol".to_string(), age: 35 },
44/// ];
45///
46/// let reversed_people = reverse(&people);
47/// assert_eq!(reversed_people, vec![
48///     Person { name: "Carol".to_string(), age: 35 },
49///     Person { name: "Bob".to_string(), age: 30 },
50///     Person { name: "Alice".to_string(), age: 25 },
51/// ]);
52/// ```
53pub fn reverse<T>(collection: &[T]) -> Vec<T>
54where
55    T: Clone,
56{
57    collection.iter().rev().cloned().collect()
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[derive(Debug, PartialEq, Clone)]
65    struct Person {
66        name: String,
67        age: u32,
68    }
69
70    #[test]
71    fn test_reverse_integers() {
72        let numbers = vec![1, 2, 3, 4, 5];
73        let reversed = reverse(&numbers);
74        assert_eq!(reversed, vec![5, 4, 3, 2, 1]);
75    }
76
77    #[test]
78    fn test_reverse_strings() {
79        let strings = vec!["apple", "banana", "cherry", "date"];
80        let reversed = reverse(&strings);
81        assert_eq!(reversed, vec!["date", "cherry", "banana", "apple"]);
82    }
83
84    #[test]
85    fn test_reverse_with_structs() {
86        let people = vec![
87            Person {
88                name: "Alice".to_string(),
89                age: 25,
90            },
91            Person {
92                name: "Bob".to_string(),
93                age: 30,
94            },
95            Person {
96                name: "Carol".to_string(),
97                age: 35,
98            },
99        ];
100
101        let reversed_people = reverse(&people);
102        assert_eq!(
103            reversed_people,
104            vec![
105                Person {
106                    name: "Carol".to_string(),
107                    age: 35
108                },
109                Person {
110                    name: "Bob".to_string(),
111                    age: 30
112                },
113                Person {
114                    name: "Alice".to_string(),
115                    age: 25
116                },
117            ]
118        );
119    }
120
121    #[test]
122    fn test_reverse_empty_collection() {
123        let empty: Vec<i32> = vec![];
124        let reversed = reverse(&empty);
125        assert_eq!(reversed, Vec::<i32>::new());
126    }
127
128    #[test]
129    fn test_reverse_single_element() {
130        let single = vec![42];
131        let reversed = reverse(&single);
132        assert_eq!(reversed, single);
133    }
134
135    #[test]
136    fn test_reverse_preserves_elements() {
137        let elements = vec![10, 20, 30, 40, 50];
138        let reversed = reverse(&elements);
139        assert_eq!(reversed, vec![50, 40, 30, 20, 10]);
140    }
141
142    #[test]
143    fn test_reverse_with_duplicates() {
144        let numbers = vec![1, 2, 2, 3, 4, 3, 5];
145        let reversed = reverse(&numbers);
146        assert_eq!(reversed, vec![5, 3, 4, 3, 2, 2, 1]);
147    }
148
149    #[test]
150    fn test_reverse_with_optionals() {
151        let collection = vec![Some(1), None, Some(2), Some(3), None];
152        let reversed = reverse(&collection);
153        assert_eq!(reversed, vec![None, Some(3), Some(2), None, Some(1)]);
154    }
155
156    #[test]
157    fn test_reverse_with_floats() {
158        let float_collection = vec![1.1, 2.2, 3.3, 4.4, 5.5];
159        let reversed = reverse(&float_collection);
160        assert_eq!(reversed, vec![5.5, 4.4, 3.3, 2.2, 1.1]);
161    }
162
163    #[test]
164    fn test_reverse_with_nan_floats() {
165        let float_collection = vec![std::f64::NAN, 2.2, std::f64::NAN, 4.4];
166        let reversed = reverse(&float_collection);
167        assert_eq!(reversed.len(), float_collection.len());
168        // Verify each element is reversed correctly
169        for i in 0..float_collection.len() {
170            if float_collection[i].is_nan() {
171                assert!(reversed[float_collection.len() - 1 - i].is_nan());
172            } else {
173                assert_eq!(
174                    reversed[float_collection.len() - 1 - i],
175                    float_collection[i]
176                );
177            }
178        }
179    }
180}