1
0
forked from Mirror/wren
Files
wren/doc/site/maps.markdown

147 lines
4.6 KiB
Markdown
Raw Normal View History

2014-01-30 06:51:52 -08:00
^title Maps
A map is an *associative* collection. It holds a set of entries, each of which
maps a *key* to a *value*. The same data structure has a variety of names in
other languages: hash table, dictionary, association, table, etc.
You can create a map by placing a series of comma-separated entries inside
curly braces. Each entry is a key and a value separated by a colon:
<pre class="snippet">
{
"George": "Harrison",
"John": "Lennon",
"Paul": "McCartney",
"Ringo": "Starr"
}
</pre>
2016-01-21 21:38:27 -08:00
This creates a map that associates the first name of each Beatle with his last
name. Syntactically, in a map literal, keys can be any literal, a variable
2015-05-03 11:10:31 -07:00
name, or a parenthesized expression. Values can be any expression. Here, we're
using string literals for both keys and values.
*Semantically*, values can be any object, and multiple keys may map to the same
value. Keys have a few limitations. They must be one of the immutable built-in
[value types][] in Wren. That means a number, string, range, bool, or `null`.
You can also use a [class object][] as a key.
[value types]: values.html
[class object]: classes.html
2015-05-03 11:10:31 -07:00
The reason for this limitation&mdash;and the reason maps are called "*hash*
tables" in other languages&mdash;is that each key is used to generate a numeric
*hash code*. This lets a map locate the value associated with a key in constant
time, even in very large maps. Since Wren only knows how to hash certain
built-in types, only those can be used as keys.
## Adding entries
2016-01-21 21:38:27 -08:00
You add new key-value pairs to the map using the [subscript operator][]:
2015-01-25 21:39:22 -08:00
[subscript operator]: method-calls.html#subscripts
<pre class="snippet">
var capitals = {}
2015-01-25 21:39:22 -08:00
capitals["Georgia"] = "Atlanta"
capitals["Idaho"] = "Boise"
capitals["Maine"] = "Augusta"
</pre>
2015-01-25 21:39:22 -08:00
2015-05-03 11:10:31 -07:00
If the key isn't already present, this adds it and associates it with the given
value. If the key is already there, this just replaces its value.
2015-01-25 21:39:22 -08:00
## Looking up values
2015-05-03 11:10:31 -07:00
To find the value associated with some key, again you use your friend the
subscript operator:
2015-01-25 21:39:22 -08:00
<pre class="snippet">
System.print(capitals["Idaho"]) //> Boise
</pre>
2015-01-25 21:39:22 -08:00
2015-05-03 11:10:31 -07:00
If the key is present, this returns its value. Otherwise, it returns `null`. Of
course, `null` itself can also be used as a value, so seeing `null` here
doesn't necessarily mean the key wasn't found.
2015-01-25 21:39:22 -08:00
To tell definitively if a key exists, you can call `containsKey()`:
<pre class="snippet">
var belief = {"nihilism": null}
2015-01-25 21:39:22 -08:00
System.print(belief["nihilism"]) //> null (though key exists)
System.print(belief["solipsism"]) //> null
System.print(belief.containsKey("nihilism")) //> true
System.print(belief.containsKey("solipsism")) //> false
</pre>
2015-01-25 21:39:22 -08:00
You can see how many entries a map contains using `count`:
<pre class="snippet">
System.print(capitals.count) //> 3
</pre>
## Removing entries
2015-05-03 11:10:31 -07:00
To remove an entry from a map, call `remove()` and pass in the key for the
entry you want to delete:
2015-01-25 21:39:22 -08:00
<pre class="snippet">
capitals.remove("Maine")
System.print(capitals.containsKey("Maine")) //> false
</pre>
2015-01-25 21:39:22 -08:00
If the key was found, this returns the value that was associated with it:
<pre class="snippet">
System.print(capitals.remove("Georgia")) //> Atlanta
</pre>
2015-01-25 21:39:22 -08:00
If the key wasn't in the map to begin with, `remove()` just returns `null`.
2016-01-21 21:38:27 -08:00
If you want to remove *everything* from the map, like with [lists][], you call
`clear()`:
2015-01-25 21:39:22 -08:00
[lists]: lists.html
<pre class="snippet">
capitals.clear()
System.print(capitals.count) //> 0
</pre>
2015-01-25 21:39:22 -08:00
## Iterating over the contents
2015-05-03 11:10:31 -07:00
The subscript operator works well for finding values when you know the key
you're looking for, but sometimes you want to see everything that's in the map.
For that, map exposes two methods: `keys` and `values`.
2015-01-25 21:39:22 -08:00
2015-05-03 11:10:31 -07:00
The first returns a [Sequence][] that [iterates][] over all of the keys in the
map, and the second returns one that iterates over the values.
2015-01-25 21:39:22 -08:00
[sequence]: modules/core/sequence.html
2015-01-25 21:39:22 -08:00
[iterates]: control-flow.html#the-iterator-protocol
2015-05-03 11:10:31 -07:00
If you want to see all of the key-value pairs in a map, the easiest way is to
iterate over the keys and use each to look up its value:
2015-01-25 21:39:22 -08:00
<pre class="snippet">
var birds = {
"Arizona": "Cactus wren",
"Hawaii": "Nēnē",
"Ohio": "Northern Cardinal"
}
for (state in birds.keys) {
System.print("The state bird of " + state + " is " + birds[state])
}
</pre>
2015-01-25 21:39:22 -08:00
2016-01-21 21:38:27 -08:00
This program prints the three states and their birds. However, the *order*
2015-05-03 11:10:31 -07:00
that they are printed isn't defined. Wren makes no promises about what order
2016-01-21 21:38:27 -08:00
keys and values are iterated in when you use these methods. All it promises is
that every entry will appear exactly once.
<br><hr>
<a class="right" href="method-calls.html">Method Calls &rarr;</a>
<a href="lists.html">&larr; Lists</a>