aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Schurhammer <julian.schurhammer@gmail.com>2022-08-11 23:57:14 +1200
committerLouis Pilfold <louis@lpil.uk>2023-03-13 10:48:28 +0000
commit240db63ea29f10810c4b55b1a9674e4aa8283d05 (patch)
tree6884fc2522769130db9375a76be2382193e4506a
parent92cbe1595c1359ab770e4ed3407dd7557e0f5f08 (diff)
downloadgleam_stdlib-240db63ea29f10810c4b55b1a9674e4aa8283d05.tar.gz
gleam_stdlib-240db63ea29f10810c4b55b1a9674e4aa8283d05.zip
implement hashCode for maps in javascript
-rw-r--r--src/persistent-hash-map.mjs15
-rw-r--r--test/gleam/map_test.gleam11
-rw-r--r--test/gleam/set_test.gleam1
3 files changed, 20 insertions, 7 deletions
diff --git a/src/persistent-hash-map.mjs b/src/persistent-hash-map.mjs
index 8cdc023..c2a792c 100644
--- a/src/persistent-hash-map.mjs
+++ b/src/persistent-hash-map.mjs
@@ -568,7 +568,7 @@ function withoutCollision(root, _shift, _hash, key) {
array: spliceOut(root.array, idx),
};
}
-function toArray(root, result) {
+function forEach(root, fn) {
if (root === undefined) {
return;
}
@@ -580,10 +580,10 @@ function toArray(root, result) {
continue;
}
if (item.type === ENTRY) {
- result.push([item.k, item.v]);
+ fn(item.v, item.k);
continue;
}
- toArray(item, result);
+ forEach(item, fn);
}
}
/** Extra wrapper to keep track of map size */
@@ -592,6 +592,13 @@ export class PMap {
this.root = root;
this.size = size;
}
+ hashCode() {
+ let h = 0;
+ forEach(this, (v, k) => {
+ h = (h + hashMerge(getHash(v), getHash(k))) | 0;
+ });
+ return h;
+ }
}
export function create() {
return new PMap(undefined, 0);
@@ -645,7 +652,7 @@ export function entries(map) {
return [];
}
const result = [];
- toArray(map.root, result);
+ forEach(map.root, (v, k) => result.push([k, v]));
return result;
}
export function __include_me() {
diff --git a/test/gleam/map_test.gleam b/test/gleam/map_test.gleam
index 2666579..34f3ee6 100644
--- a/test/gleam/map_test.gleam
+++ b/test/gleam/map_test.gleam
@@ -2,6 +2,8 @@ import gleam/map
import gleam/option.{None, Some}
import gleam/should
import gleam/string
+import gleam/list
+import gleam/int
pub fn from_list_test() {
[#(4, 0), #(1, 0)]
@@ -103,6 +105,7 @@ pub fn keys_test() {
[#("a", 0), #("b", 1), #("c", 2)]
|> map.from_list
|> map.keys
+ |> list.sort(string.compare)
|> should.equal(["a", "b", "c"])
}
@@ -110,6 +113,7 @@ pub fn values_test() {
[#("a", 0), #("b", 1), #("c", 2)]
|> map.from_list
|> map.values
+ |> list.sort(int.compare)
|> should.equal([0, 1, 2])
}
@@ -189,11 +193,12 @@ pub fn fold_test() {
|> map.fold(0, add)
|> should.equal(6)
- let concat = fn(acc, k, _) { string.append(acc, k) }
+ let prepend = fn(acc, k, _) { list.prepend(acc, k) }
dict
- |> map.fold("", concat)
- |> should.equal("abcd")
+ |> map.fold([], prepend)
+ |> list.sort(string.compare)
+ |> should.equal(["a", "b", "c", "d"])
map.from_list([])
|> map.fold(0, add)
diff --git a/test/gleam/set_test.gleam b/test/gleam/set_test.gleam
index aae5256..123dc43 100644
--- a/test/gleam/set_test.gleam
+++ b/test/gleam/set_test.gleam
@@ -70,6 +70,7 @@ pub fn filter_test() {
|> set.from_list()
|> set.filter(for: int.is_even)
|> set.to_list
+ |> list.sort(int.compare)
|> should.equal([4, 6, 44])
}