Skip to content

Commit 11ebb2a

Browse files
authored
Merge pull request #410 from elixirscript/fix-map-equality
Add map functions to check for equality of keys
2 parents b8f2478 + 9b19589 commit 11ebb2a

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

src/javascript/lib/core/erlang_compat/maps.js

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,63 @@ const ERROR = Symbol.for('error');
77
const BADMAP = Symbol.for('badmap');
88
const BADKEY = Symbol.for('badkey');
99

10+
function is_non_primitive(key) {
11+
return (
12+
erlang.is_list(key) ||
13+
erlang.is_map(key) ||
14+
erlang.is_pid(key) ||
15+
erlang.is_reference(key) ||
16+
erlang.is_bitstring(key) ||
17+
erlang.is_tuple(key)
18+
);
19+
}
20+
21+
function __has(map, key) {
22+
if (is_non_primitive(key)) {
23+
for (const map_key of map.keys()) {
24+
if (erlang.equals(map_key, key)) {
25+
return true;
26+
}
27+
}
28+
29+
return false;
30+
}
31+
32+
return map.has(key);
33+
}
34+
35+
function __get(map, key) {
36+
if (is_non_primitive(key)) {
37+
for (const map_key of map.keys()) {
38+
if (erlang.equals(map_key, key)) {
39+
return map.get(map_key);
40+
}
41+
}
42+
43+
return null;
44+
}
45+
46+
return map.get(key);
47+
}
48+
49+
function __delete(map, key) {
50+
if (is_non_primitive(key)) {
51+
for (const map_key of map.keys()) {
52+
if (erlang.equals(map_key, key)) {
53+
map.delete(map_key);
54+
}
55+
}
56+
} else {
57+
map.delete(key);
58+
}
59+
}
60+
1061
function find(key, map) {
1162
if (erlang.is_map(map) === false) {
1263
return new ErlangTypes.Tuple(BADMAP, map);
1364
}
1465

15-
const value = map.get(key);
66+
const value = __get(map, key);
1667

1768
if (typeof value !== 'undefined') {
1869
return new ErlangTypes.Tuple(OK, value);
@@ -38,7 +89,7 @@ function remove(key, map1) {
3889

3990
const map2 = new Map(map1);
4091

41-
map2.delete(key);
92+
__delete(map2, key);
4293

4394
return map2;
4495
}
@@ -83,7 +134,7 @@ function values(map) {
83134
}
84135

85136
function is_key(key, map) {
86-
return map.has(key);
137+
return __has(map, key);
87138
}
88139

89140
function put(key, value, map1) {
@@ -130,7 +181,7 @@ function get(...args) {
130181
}
131182

132183
if (is_key(key)) {
133-
return map.get(key);
184+
return __get(map, key);
134185
}
135186

136187
if (args.length === 3) {
@@ -149,9 +200,9 @@ function take(key, map1) {
149200
return ERROR;
150201
}
151202

152-
const value = map1.get(key);
203+
const value = __get(map1, key);
153204
const map2 = new Map(map1);
154-
map2.delete(key);
205+
__delete(map2, key);
155206

156207
return new ErlangTypes.Tuple(value, map2);
157208
}
@@ -170,4 +221,5 @@ export default {
170221
update,
171222
get,
172223
take,
224+
__has,
173225
};

src/javascript/tests/core/erlang_compat/maps_spec.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,37 @@ test('find', (t) => {
1313
myMap = new Map([['t', 'b']]);
1414
result = Core.maps.find('t', myMap);
1515
t.deepEqual(result.values, [Symbol.for('ok'), 'b']);
16+
17+
myMap = new Map([[[1], 'b']]);
18+
result = Core.maps.find([1], myMap);
19+
t.deepEqual(result.values, [Symbol.for('ok'), 'b']);
20+
21+
myMap = new Map([[new Map(), 'b']]);
22+
result = Core.maps.find(new Map(), myMap);
23+
t.deepEqual(result.values, [Symbol.for('ok'), 'b']);
1624
});
1725

1826
test('fold', (t) => {
1927
const myMap = new Map([['a', 1], ['b', 2]]);
2028
const result = Core.maps.fold((k, v, acc) => acc + v, 0, myMap);
2129
t.is(result, 3);
2230
});
31+
32+
test('is_key', (t) => {
33+
const myMap = new Map([['a', 1], ['b', 2]]);
34+
let result = Core.maps.is_key('a', myMap);
35+
t.is(result, true);
36+
37+
result = Core.maps.is_key('c', myMap);
38+
t.is(result, false);
39+
});
40+
41+
test('remove', (t) => {
42+
let myMap = new Map([['a', 1], ['b', 2]]);
43+
let result = Core.maps.remove('a', myMap);
44+
t.is(result.has('a'), false);
45+
46+
myMap = new Map([[[1], 1], ['b', 2]]);
47+
result = Core.maps.remove([1], myMap);
48+
t.is(Core.maps.__has(result, [1]), false);
49+
});

0 commit comments

Comments
 (0)