#combine #structure #together

amalgamator

A set/map like data structure that allows you to combine members together

1 unstable release

0.1.0 Jul 25, 2024

#774 in Data structures

MIT/Apache

27KB
579 lines

amalgamator

Description

amalgamator is a set/map like data structure that allows you to combine members of the set/map together based on some criteria.

This is useful when you want to merge objects together that aren't strictly equal, but are similar enough that you want to treat them as the same object.

Installation

cargo add amalgamator

Serde Support

If you want to use serde support, you can enable the serde feature.

cargo add amalgamator --features serde

Documentation

View the docs on the docs.rs Documentation page.

License

This project is licensed under the MIT license or the Apache 2.0 license, at your option.


lib.rs:

amalgamator is a set/map like data structure that allows you to combine members of the set/map together based on some criteria. This is useful when you want to merge objects together that aren't strictly equal, but are similar enough that you want to treat them as the same object.

This can be useful in a variety of situations, such as:

  • Merging data from multiple sources
  • Entity deduplication
  • Data normalization

Amalgamator is implemented as a set/map like data structure, generic over the type of the elements it contains. Amalgamator uses a user-defined function to determine if two elements should be combined and a user-defined function to merge two elements together. This is the Amalgamate trait.

Lets first take a look at how we might implement Amalgamate trait:

use amalgamator::Amalgamate;
use std::collections::HashSet;

struct Person {
    name: String,
    friends: HashSet<String>,
}

impl Amalgamate for Person {
    type Key = String;

    fn key(&self) -> Self::Key {
        self.name.clone()
    }

    fn amalgamate(&mut self, other: Self) {
        self.friends.extend(other.friends);
    }
}

In this example, we have a Person struct that has a name and a set of friends. We implement the Amalgamate trait for Person by defining the Key type as String and implementing the key and amalgamate functions. We assume that the value of the name field is unique to each person, so we use it as the key to determine if two Person objects should be combined.

Now that we have implemented the Amalgamate trait, we can use the Amalgamator data structure to combine Person objects together. Better yet, we can use it just like a regular set/map data structure.

use amalgamator::Amalgamator;
#
#
#

let mut amalgamator = Amalgamator::new();

let alice = Person {
    name: "Alice".to_string(),
    friends: ["Bob", "Charlie"].iter().map(|s| s.to_string()).collect(),
};

let bob = Person {
    name: "Bob".to_string(),
    friends: ["Alice", "Charlie"].iter().map(|s| s.to_string()).collect(),
};

let other_alice = Person {
    name: "Alice".to_string(),
    friends: ["David", "Eve"].iter().map(|s| s.to_string()).collect(),
};

amalgamator.add(alice);
amalgamator.add(bob);
amalgamator.add(other_alice);

assert_eq!(amalgamator.len(), 2);

let alice = &amalgamator["Alice"];
assert_eq!(alice.friends.len(), 4);

In this example, we create an Amalgamator and add three Person objects to it. We then verify that the Amalgamator contains only two Person objects, as the two Alice objects (with the same name) have been combined. We then retrieve the Alice object from the Amalgamator and verify that it has all the friends from both Alice objects.

Features

  • serde: Enables serialization and deserialization of Amalgamator using Serde.

Dependencies

~165KB