Hi!
Let's assume we have a collection of these tuples:
[
('t', "tea"),
('t', "text"),
('t', "task"),
('c', "cat"),
('c', "crab")
('c', "car"),
('a', "apple"),
('a', "ample"),
]
Is there a way to use some combination of iterator adapters to make this a collection like:
[
('t', vec!["tea", "text", "task"]),
('c', vec!["cat", "crab", "car"]),
('a', vec!["apple", "ample"]),
]
So I would be able to collect this to a HashMap
.
I might be being a bit ambiguous here, does the example make sense?
Thanks!
Thanks, but won't this only keep the "task"
value for the 't'
key only, as the previous values would be overwritten by it? This will collect them into a HashMap<char, &str>
, but I need HashMap<char, Vec<&str>>
.
Am I missing something?
Sorry, should've payed more attention! This should work:
let mut my_map = HashMap::new();
for (c, s) in my_tuples {
my_map.entry(&c).or_insert_with(Vec::new).push(s);
}
4 Likes
Thanks, so there is no way to use iterator adapters to modify produce the collection before collecting it to a HashMap
?
H2CO3
July 29, 2021, 8:52pm
6
Why would you want to modify it? It seems to me you want the opposite: a "pure" iterator adaptor solution, that collects directly into a HashMap<String, Vec<_>>
. If you are willing to pull in itertools
, you can do it with the group_by
extension method, as in this Playground .
3 Likes
You can still use iterator adaptors in a for
loop, like:
for (c, s) in my_tuples.into_iter().filter(|(c,_)| c.is_lowercase()) {
my_map.entry(c).or_default().push(s);
}
You could also transform any for
loop into a call to for_each
or fold
, like:
let my_map: HashMap<char, Vec<&str>> = tuples
.into_iter()
.filter(|(c,_)| c.is_lowercase())
.fold(HashMap::new(), |mut map, (c, s)| {
map.entry(c).or_default().push(s);
map
});
4 Likes
Thanks, @H2CO3 ! I was really looking for a solution like yours and you're right I worded it wrong in my earlier reply!
Thanks, @cole-miller @mbrubeck for your inputs too!
system
Closed
October 28, 2021, 6:38am
9
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.