# Is there a stable type like a HashMap where the key can be of Principal type and the value a custom type?

**URL:** <https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020>\
**Category:** Language Support\
**Created:** [January 17, 2023, 10:01pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020 "2023-01-17T22:01:03Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 17, 2023, 10:01pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/1 "2023-01-17T22:01:03Z")

</div>

Basically seeking something like this:

` stable var users : HashMap.HashMap<Principal, UserData> = HashMap.empty();`

Where for example

```auto
type UserData = {
    principal : Principal;
    favorite_color : Text;
    name : Text;
    favorite_number : Nat;
  };

```

---

<div class="post-metadata">

**Author:** ![Gekctek](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/gekctek/32/6863_2.png) [@Gekctek](https://forum.dfinity.org/u/Gekctek)\
**Post date:** [January 17, 2023, 11:30pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/2 "2023-01-17T23:30:54Z")

</div>

Not that I have seen.

I know there was a stable b-tree implementation but i havent used it myself

> **[GitHub - sardariuss/MotokoStableBTree:...](https://github.com/sardariuss/MotokoStableBTree)**
>
> https://forum.dfinity.org/t/icdevs-org-bounty-24-stablebtree-mokoko-up-to-10k/14867 - GitHub - sardariuss/MotokoStableBTree: https://forum.dfinity.org/t/icdevs-org-bounty-24-stablebtree-mokoko-up-t...

> **[Bounty - ICDevs.org Motoko StableBTree](https://icdevs.org/bounties/2022/08/14/Motoko-StableBTree.html)**
>
> A US 501(c)3 non-profit benefiting the Internet Computer and DFINITY ecosystem. Grants. Bounties. Education. Tutorials. Utilities. Open Source.

Otherwise what you would do is have a stable variable that was like a array or another stable data structure

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 18, 2023, 1:24am UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/3 "2023-01-18T01:24:39Z")

</div>

Thank you, I ended up using this for now. As far as I can tell, HashMap is a far better structure than Trie to store principals as keys.

> **[GitHub - ClankPan/StableHashMap](https://github.com/ClankPan/StableHashMap)**
>
> Contribute to ClankPan/StableHashMap development by creating an account on GitHub.

My worry are bugs and security vulnerabilities since it seems to be a little known repo, but really the natural structure is HashMap so I’ll use this for now.

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [January 18, 2023, 8:41am UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/4 "2023-01-18T08:41:10Z")

</div>

How about `RBTree`? (Which should perhaps better be named `TreeMap` or something like that.)

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [January 18, 2023, 11:45am UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/5 "2023-01-18T11:45:53Z")

</div>

We use both motoko-hash-map and the migration pattern in the latest version of axon. See: [axon/lib.mo at da8601a65fce0d2536971bca562538fa39f1cd53 · icdevs/axon · GitHub](https://github.com/icdevs/axon/blob/da8601a65fce0d2536971bca562538fa39f1cd53/src/Axon/migrations/v002_000_001/lib.mo#L23) for the ledger implementation.

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 18, 2023, 12:25pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/6 "2023-01-18T12:25:36Z")

</div>

> [@rossberg](#):
>
> How about `RBTree`?

Is it stable?

I see

` stable var rb_users = RBTree.RBTree<Principal, UserData>(Principal.compare);`

```auto
variable rb_users is declared stable but has non-stable type
  RBTree<Principal, UserData>Motoko

```

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 18, 2023, 12:27pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/7 "2023-01-18T12:27:25Z")

</div>

> [@skilesare](#):
>
> We use both motoko-hash-map and the migration pattern in the latest version of axon.

Are there major advantages of doing this over StableHashMap?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [January 18, 2023, 1:47pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/8 "2023-01-18T13:47:57Z")

</div>

Likely yes. I haven’t tested it against that library explicitly, but check this thread: [∞ Day - Origyn Motoko Gift 2 - A Better Map](https://forum.dfinity.org/t/day-origyn-motoko-gift-2-a-better-map/14758)

---

<div class="post-metadata">

**Author:** ![pk34](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/pk34/32/3648_2.png) [@pk34](https://forum.dfinity.org/u/pk34)\
**Post date:** [January 31, 2023, 2:24pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/9 "2023-01-31T14:24:42Z")

</div>

I work with something like this:

For the types

```auto
/// Users
    public type UserID = Principal;
    public type Username = Text;
    public type UserData = {
        username : Username;
        banned : Bool;
    };

```

The HashMaps

```auto
/// We create an array as a stable var, since hashmaps are not stable
private stable var _users : [(UserID, UserData)] = [];

/// Then we create the hashmap and initialize it from the _users array
var users : HashMap.HashMap<UserID, UserData> = HashMap.fromIter(_users.vals(), 0, Principal.equal, Principal.hash);

```

And to keep them on every update

```auto
//State functions
    system func preupgrade() {
        /// Before an update we put all values from the hashmap to the array, so they can be preserved
        _users := Iter.toArray(users.entries());
    };
    system func postupgrade() {
        /// And since the hashmap is initialized with all the values from the stable array, we can reset the array so in the next update values don't duplicate
        _users := [];
    };

```

I hope this can help with your main problem (:

---

<div class="post-metadata">

**Author:** ![blabagastered](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/blabagastered/32/8592_2.png) [@blabagastered](https://forum.dfinity.org/u/blabagastered)\
**Post date:** [January 31, 2023, 2:43pm UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/10 "2023-01-31T14:43:15Z")

</div>

> [@pk34](#):
>
> I hope this can help with your main problem (:

Thank you, I ended up using this on @skilesare’s advice elsewhere, which I believe doesn’t require pre-postupgrade: [GitHub - ZhenyaUsenko/motoko-hash-map: Stable hash maps for Motoko](https://github.com/ZhenyaUsenko/motoko-hash-map)

---

<div class="post-metadata">

**Author:** ![jaxopaxo](https://avatars.discourse-cdn.com/v4/letter/j/b5ac83/32.png) [@jaxopaxo](https://forum.dfinity.org/u/jaxopaxo)\
**Post date:** [April 8, 2024, 9:52am UTC](https://forum.dfinity.org/t/is-there-a-stable-type-like-a-hashmap-where-the-key-can-be-of-principal-type-and-the-value-a-custom-type/18020/11 "2024-04-08T09:52:58Z")

</div>

This is working well, I added below

let users = HashMap.HashMap\<Principal, User\>(0, Principal.equal, Principal.hash);  
private stable var \_users : [(Principal, User)] = ;

//State functions  
system func preupgrade() {  
/// Before an update we put all values from the hashmap to the array, so they can be preserved  
\_users := Iter.toArray(users.entries());  
};  
system func postupgrade() {  
/// And since the hashmap is initialized with all the values from the stable array, we can reset the array so in the next update values don’t duplicate  
for ( (p, al ) in \_users.vals() ) {  
users.put(p, al);  
};  
\_users := ;  
};
