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
/// Find the key in a map that satisfies a predicate based on both key and value.
/// If no key satisfies the predicate, return None.
///
/// # Arguments
/// * `object` - A map of key-value pairs.
/// * `predicate` - A function that takes a key and value and returns a boolean.
///
/// # Returns
/// * `Option<&K>` - The key that satisfies the predicate, or None if no key satisfies the predicate.
///
/// # Examples
/// ```rust
/// use lowdash::find_key_by;
/// let mut map = std::collections::HashMap::new();
/// map.insert("a", 1);
/// map.insert("b", 2);
/// map.insert("c", 3);
/// let result = find_key_by(&map, |k, v| *k == "b" && *v == 2);
/// assert_eq!(result, Some(&"b"));
/// ```
///
/// ```rust
/// use lowdash::find_key_by;
/// let mut map = std::collections::HashMap::new();
/// map.insert("a", 1);
/// map.insert("b", 2);
/// map.insert("c", 3);
/// let result = find_key_by(&map, |_, v| *v > 2);
/// assert_eq!(result, Some(&"c"));
/// ```
pub fn find_key_by<K, V, F>(object: &std::collections::HashMap<K, V>, predicate: F) -> Option<&K>
where
K: std::cmp::Eq + std::hash::Hash,
F: Fn(&K, &V) -> bool,
{
for (k, v) in object {
if predicate(k, v) {
return Some(k);
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
#[test]
fn test_find_key_by() {
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let result = find_key_by(&map, |k, v| *k == "b" && *v == 2);
assert_eq!(result, Some(&"b"));
}
#[test]
fn test_find_key_by_value_only() {
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let result = find_key_by(&map, |_, v| *v > 2);
assert_eq!(result, Some(&"c"));
}
#[test]
fn test_find_key_by_not_found() {
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let result = find_key_by(&map, |_, v| *v > 3);
assert_eq!(result, None);
}
#[test]
fn test_find_key_by_empty_map() {
let map: HashMap<&str, i32> = HashMap::new();
let result = find_key_by(&map, |_, v| *v == 1);
assert_eq!(result, None);
}
#[test]
fn test_find_key_by_with_struct() {
#[derive(Debug, PartialEq)]
struct Person {
name: String,
age: u32,
}
let mut map = HashMap::new();
map.insert(
"dev1",
Person {
name: "Alice".to_string(),
age: 25,
},
);
map.insert(
"dev2",
Person {
name: "Bob".to_string(),
age: 30,
},
);
map.insert(
"dev3",
Person {
name: "Carol".to_string(),
age: 35,
},
);
let result = find_key_by(&map, |_, p| p.age > 30);
assert_eq!(result, Some(&"dev3"));
let name_result = find_key_by(&map, |k, p| k.starts_with("dev2") && p.name == "Bob");
assert_eq!(name_result, Some(&"dev2"));
let not_found = find_key_by(&map, |_, p| p.age > 40);
assert_eq!(not_found, None);
}
}