#key-value #collection #pair #collect #map #mapping #aggregate

aggregate-map

Collect key-values pairs into a mapping from keys to collections of values

2 stable releases

1.0.1 May 12, 2024

#922 in Data structures

Download history 202/week @ 2024-05-06 91/week @ 2024-05-13 20/week @ 2024-05-20

313 downloads per month

Unlicense

8KB
76 lines

aggregate-map

Easily collect a list of key-value pairs into a mapping of keys to collections of values in Rust.


lib.rs:

Collect a list of key-value pairs into a mapping of keys to collections of values.

If you have a set of data that you want to collect into a map, by default you'll only keep the last value in the data for that key. But what if you want instead to keep a collection of all the values for each key? Enter AggregateMap!

let data = [
    ("dog", "Terry"),
    ("dog", "Zamboni"),
    ("cat", "Jonathan"),
    ("dog", "Priscilla"),
];
let collected: AggregateMap<HashMap<_, Vec<_>>> = data.into_iter().collect();
let expected = HashMap::from([
    ("dog", vec!["Terry", "Zamboni", "Priscilla"]),
    ("cat", vec!["Jonathan"])
]);
assert_eq!(collected.into_inner(), expected);

AggregateMap can be used with any map type that implements this crate's [Map] trait, such as HashMap or BTreeMap.

The collection type doesn't have to be a [Vec], too, it can be anything that implements Extend and Default. For instance, here's an example with a HashSet:

let data = [
    ("dog", "Terry"),
    ("dog", "Terry"),
    ("dog", "Priscilla"),
];
let collected: AggregateMap<HashMap<_, HashSet<_>>> = data.into_iter().collect();
let expected = HashMap::from([
    ("dog", HashSet::from(["Terry", "Priscilla"])),
]);
assert_eq!(collected.into_inner(), expected);

It can even be another AggregateMap for additional levels of aggregation!

let data = [
    ("pet", ("dog", "Terry")),
    ("pet", ("dog", "Priscilla")),
    ("stray", ("cat", "Jennifer")),
    ("pet", ("cat", "Absalom")),
];
let collected: AggregateMap<HashMap<_, AggregateMap<HashMap<_, Vec<_>>>>> =
    data.into_iter().collect();
let expected = HashMap::from([
    ("pet", HashMap::from([
        ("dog", vec!["Terry", "Priscilla"]),
        ("cat", vec!["Absalom"]),
    ])),
    ("stray", HashMap::from([
        ("cat", vec!["Jennifer"]),
    ])),
]);
let collected: HashMap<_, _> = collected
    .into_inner()
    .into_iter()
    .map(|(key, map)| (key, map.into_inner()))
    .collect();
assert_eq!(collected, expected);

Dependencies

~175KB