1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
use std::{collections::HashSet, hash::Hash};
use std::collections::HashMap;
/// Collection-related utility classes, such as for intersections, unions, reversal, element removal, etc.
pub struct CollectionUtil;
/// vec常规操作
impl CollectionUtil {
pub fn is_empty<T>(vec: &[T]) -> bool {
vec.is_empty()
}
pub fn is_not_empty<T>(vec: &[T]) -> bool {
!vec.is_empty()
}
/// 获取vec的第一个元素,不移除
pub fn first<T>(vec: &[T]) -> Option<&T> {
vec.get(0)
}
pub fn second<T>(vec: &[T]) -> Option<&T> {
vec.get(1)
}
pub fn third<T>(vec: &[T]) -> Option<&T> {
vec.get(2)
}
/// 移除并获取vec的第一个元素
pub fn remove_first<T>(vec: &mut Vec<T>) -> Option<T> {
if vec.len() > 0 { Some(vec.remove(0)) } else { None }
}
/// 获取vec的最后一个元素,不移除
pub fn last<T>(vec: &[T]) -> Option<&T> {
vec.last()
}
/// 获取vec的最后一个元素,移除
pub fn pop<T>(vec: &mut Vec<T>) -> Option<T> {
vec.pop()
}
/// 反转向量中的元素顺序
pub fn reverse<T>(vec: &mut [T]) {
vec.reverse()
}
/// 移除重复的元素
pub fn distinct<T: Eq + Hash + Clone>(vec: &[T]) -> Vec<T> {
let mut hash_set = HashSet::new();
for item in vec.iter() {
hash_set.insert(item.clone());
}
hash_set.into_iter().collect()
}
/// 找到切片中的最大元素
pub fn max<T: Ord>(vec: &[T]) -> Option<&T>{
vec.iter().max()
}
/// 找到切片中的最小元素
pub fn min<T: Ord>(vec: &[T]) -> Option<&T>{
vec.iter().min()
}
/// 将两个切片连接成一个新的向量
///
/// 该函数接收两个相同类型的切片,并将它们的元素按顺序复制到一个新的向量中。
/// 使用预分配容量的方式来提高内存分配效率。
///
/// # 参数
/// * `vec1` - 第一个切片引用,其元素将出现在结果向量的前面部分
/// * `vec2` - 第二个切片引用,其元素将出现在结果向量的后面部分
///
/// # 返回值
/// 返回一个包含两个输入切片所有元素的新向量,元素顺序保持不变
///
/// # 泛型约束
/// * `T: Copy` - 要求元素类型实现Copy trait,以便能够复制元素
pub fn concat_slices<T: Copy>(vec1: &[T], vec2: &[T]) -> Vec<T> {
let mut result = Vec::with_capacity(vec1.len() + vec2.len()); // 预分配容量,提高效率
result.extend(vec1.iter().copied());
result.extend(vec2.iter().copied());
result
}
/// 对切片进行排序
///
/// 该函数使用标准库的排序算法对给定切片进行原地排序
///
/// # 参数
///
/// * `vec` - 需要排序的可变切片引用
///
/// # 泛型约束
///
/// * `T` - 必须实现 `Ord` trait,即支持全序比较
pub fn sort<T>(vec: &mut [T]) where T: Ord {
vec.sort()
}
/// 将切片中的元素映射到HashMap中,使用指定的键提取函数生成键
///
/// # 参数
/// * `vec` - 包含值的切片引用
/// * `key_fn` - 用于从值中提取键的函数
///
/// # 返回值
/// 返回一个HashMap,其中键是通过key_fn函数从值中提取的,值是对原切片中元素的引用
///
/// # 泛型参数
/// * `K` - HashMap的键类型,必须实现Eq和Hash trait
/// * `V` - 切片中值的类型
/// * `Accessor` - 键提取函数的类型,必须是一个接受&V并返回K的函数
pub fn mapping<K, V, Accessor>(vec: &[V], key_fn: Accessor) -> HashMap<K, &V>
where
K: Eq + Hash,
Accessor: Fn(&V) -> K
{
// 创建一个新的HashMap来存储映射结果
let mut map = HashMap::new();
// 遍历切片中的每个元素,将键值对插入到HashMap中
for item in vec.iter() {
map.insert(key_fn(item), item);
}
map
}
/// 按指定规则对切片中的元素进行分组
///
/// 该函数接收一个切片和一个键生成函数,将切片中的元素按照键生成函数的结果进行分组,
/// 返回一个 HashMap,其中键为分组依据,值为属于该分组的元素引用组成的向量。
///
/// # 参数
/// * `vec` - 需要分组的元素切片
/// * `key_fn` - 键生成函数,用于为每个元素生成分组依据
///
/// # 返回值
/// 返回一个 HashMap,键类型为 K,值类型为 Vec<&V>,包含所有分组结果
///
/// # 泛型参数
/// * `K` - 分组键的类型,必须实现 Eq 和 Hash trait
/// * `V` - 切片中元素的类型
/// * `Accessor` - 键生成函数的类型,必须实现 Fn(&V) -> K
pub fn group_by<K, V, Accessor>(vec: &[V], key_fn: Accessor) -> HashMap<K, Vec<&V>>
where
K: Eq + Hash,
Accessor: Fn(&V) -> K
{
let mut map = HashMap::new();
// 遍历切片中的每个元素,按 key_fn 生成的键进行分组
for item in vec.iter() {
// 为当前元素生成 key
let key = key_fn(&item);
// 将元素插入对应 key 的 Vec 中(不存在则自动创建)
map.entry(key).or_insert_with(Vec::new).push(item);
}
map
}
/// 计算交集:两个集合中都存在的元素
pub fn intersection<T>(vec1: Vec<T>, vec2: Vec<T>) -> Vec<T>
where T: Eq + Hash + Clone {
// 转换为HashSet
let set1: HashSet<T> = vec1.into_iter().collect();
let set2: HashSet<T> = vec2.into_iter().collect();
// 计算交集:两个集合中都存在的元素
let result: Vec<T> = set1.intersection(&set2).cloned().collect();
result
}
/// 计算并集:两个集合中所有不重复的元素
pub fn union<T>(vec1: Vec<T>, vec2: Vec<T>) -> Vec<T>
where T: Eq + Hash + Clone {
let set1: HashSet<T> = vec1.into_iter().collect();
let set2: HashSet<T> = vec2.into_iter().collect();
// 计算并集:两个集合中所有不重复的元素
let result: Vec<_> = set1.union(&set2).cloned().collect();
result
}
/// 计算差集:set1中有而set2中没有的元素
pub fn difference<T>(vec1: Vec<T>, vec2: Vec<T>) -> Vec<T>
where T: Eq + Hash + Clone {
let set1: HashSet<T> = vec1.into_iter().collect();
let set2: HashSet<T> = vec2.into_iter().collect();
// 计算差集:set1中有而set2中没有的元素
let result: Vec<_> = set1.difference(&set2).cloned().collect();
result
}
/// 计算对称差集:只在其中一个集合中出现的元素
pub fn symmetric_difference<T>(vec1: Vec<T>, vec2: Vec<T>) -> Vec<T>
where T: Eq + Hash + Clone {
let set1: HashSet<T> = vec1.into_iter().collect();
let set2: HashSet<T> = vec2.into_iter().collect();
// 计算对称差集:只在其中一个集合中出现的元素
let result: Vec<_> = set1.symmetric_difference(&set2).cloned().collect();
result
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
#[test]
fn test_remove_first() {
let _map = HashMap::<i32, i32>::new();
}
}