1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Highly specific, but useful, collections-related classes.
16 module more_collections
18 # Simple way to store an `HashMap[K, Array[V]]`
20 # Unlike standard HashMap, MultiHashMap provides a new
21 # empty array on the first access on a unknown key.
23 # var m = new MultiHashMap[String, Char]
24 # assert not m.has_key("four")
29 # assert m.has_key("four")
30 # assert m["four"] == ['i', 'i', 'i', 'i']
31 # assert m["zzz"] == new Array[Char]
32 class MultiHashMap[K
, V
]
33 super HashMap[K
, Array[V
]]
35 # Add `v` to the array associated with `k`.
36 # If there is no array associated, then create it.
37 fun add_one
(k
: K
, v
: V
)
39 var x
= self.get_or_null
(k
)
47 redef fun provide_default_value
(key
) do
48 var res
= new Array[V
]
54 # Simple way to store an `HashMap[K1, HashMap[K2, V]]`
57 # var hm2 = new HashMap2[Int, String, Float]
60 # assert hm2[1, "one"] == 1.0
61 # assert hm2[2, "not-two"] == null
63 class HashMap2[K1, K2, V
]
64 private var level1
= new HashMap[K1, HashMap[K2, V
]]
66 # Return the value associated to the keys `k1` and `k2`.
67 # Return `null` if no such a value.
68 fun [](k1
: K1, k2
: K2): nullable V
70 var level1
= self.level1
71 var level2
= level1
.get_or_null
(k1
)
72 if level2
== null then return null
73 return level2
.get_or_null
(k2
)
76 # Set `v` the value associated to the keys `k1` and `k2`.
77 fun []=(k1
: K1, k2
: K2, v
: V
)
79 var level1
= self.level1
80 var level2
= level1
.get_or_null
(k1
)
81 if level2
== null then
82 level2
= new HashMap[K2, V
]
88 # Remove the item at `k1` and `k2`
89 fun remove_at
(k1
: K1, k2
: K2)
91 var level1
= self.level1
92 var level2
= level1
.get_or_null
(k1
)
93 if level2
== null then return
94 level2
.keys
.remove
(k2
)
98 fun clear
do level1
.clear
101 # Simple way to store an `HashMap[K1, HashMap[K2, HashMap[K3, V]]]`
104 # var hm3 = new HashMap3[Int, String, Int, Float]
105 # hm3[1, "one", 11] = 1.0
106 # hm3[2, "two", 22] = 2.0
107 # assert hm3[1, "one", 11] == 1.0
108 # assert hm3[2, "not-two", 22] == null
110 class HashMap3[K1, K2, K3, V
]
111 private var level1
= new HashMap[K1, HashMap2[K2, K3, V
]]
113 # Return the value associated to the keys `k1`, `k2`, and `k3`.
114 # Return `null` if no such a value.
115 fun [](k1
: K1, k2
: K2, k3
: K3): nullable V
117 var level1
= self.level1
118 var level2
= level1
.get_or_null
(k1
)
119 if level2
== null then return null
120 return level2
[k2
, k3
]
123 # Set `v` the value associated to the keys `k1`, `k2`, and `k3`.
124 fun []=(k1
: K1, k2
: K2, k3
: K3, v
: V
)
126 var level1
= self.level1
127 var level2
= level1
.get_or_null
(k1
)
128 if level2
== null then
129 level2
= new HashMap2[K2, K3, V
]
135 # Remove the item at `k1`, `k2` and `k3`
136 fun remove_at
(k1
: K1, k2
: K2, k3
: K3)
138 var level1
= self.level1
139 var level2
= level1
.get_or_null
(k1
)
140 if level2
== null then return
141 level2
.remove_at
(k2
, k3
)
145 fun clear
do level1
.clear
148 # A map with a default value.
151 # var dm = new DefaultMap[String, Int](10)
152 # assert dm["a"] == 10
155 # The default value is used when the key is not present.
156 # And getting a default value does not register the key.
159 # assert dm["a"] == 10
160 # assert dm.length == 0
161 # assert dm.has_key("a") == false
164 # It also means that removed key retrieve the default value.
168 # assert dm["a"] == 2
169 # dm.keys.remove("a")
170 # assert dm["a"] == 10
173 # Warning: the default value is used as is, so using mutable object might
174 # cause side-effects.
177 # var dma = new DefaultMap[String, Array[Int]](new Array[Int])
180 # assert dma["a"] == [65]
181 # assert dma.default == [65]
182 # assert dma["c"] == [65]
185 # assert dma["b"] == [65, 66]
186 # assert dma.default == [65]
188 class DefaultMap[K
, V
]
194 redef fun provide_default_value
(key
) do return default