a381820f7971

Dicts.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Wed, 26 Oct 2011 01:17:40 -0400
parents 2ec4586dd43a
children 02d1c7c8455d
branches/tags (none)
files chapters/37.markdown outline.org

Changes

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chapters/37.markdown	Wed Oct 26 01:17:40 2011 -0400
@@ -0,0 +1,140 @@
+Dictionaries
+============
+
+The last type of Vimscript variable we'll talk about is the dictionary.
+Vimscript dictionaries are similar to Python's dicts, Ruby's hashes, and
+Javascript's objects.
+
+Dictionaries are created using curly brackets.  Values are heterogeneous, but
+*keys are always coerced to strings*.  You didn't think things were going to be
+*completely* sane, did you?
+
+Run this command:
+
+    :echo {'a': 1, 100: 'foo'}
+
+Vim displays `{'a': 1, '100': 'foo'}`, which shows that Vimscript does indeed
+coerce keys to strings while leaving values alone.
+
+Vimscript avoids the stupidity of the Javascript standard and lets you use
+a comma after the last element in a dictionary.  Run the following command:
+
+    :echo {'a': 1, 100: 'foo',}
+
+Once again Vim displays `{'a': 1, '100': 'foo'}`.  You should *always* use the
+trailing comma in your dictionaries, *especially* when they're defined on
+multiple lines, because it will make adding new entries less error-prone.
+
+Indexing
+--------
+
+To look up a key in a dictionary you use the same syntax as most languages.  Run
+this command:
+
+    :echo {'a': 1, 100: 'foo',}['a']
+
+Vim displays `1`.  Try it with a non-string index:
+
+    :echo {'a': 1, 100: 'foo',}[100]
+
+Vim coerces the index to a string before performing the lookup, which makes
+sense since keys can only ever be strings.
+
+Vimscript also supports the Javascript-style "dot" lookup when the key is
+a string consisting only of letters, digits and/or underscores.  Try the
+following commands:
+
+    :echo {'a': 1, 100: 'foo',}.a
+    :echo {'a': 1, 100: 'foo',}.100
+
+Vim displays the correct element in both cases.  How you choose to index your
+dictionaries is a matter of taste and style.
+
+Assigning and Adding
+--------------------
+
+Adding entries to dictionaries is done by simply assigning them like variables.
+Run this command:
+
+    :let foo = {'a': 1}
+    :let foo.a = 100
+    :let foo.b = 200
+    :echo foo
+
+Vim displays `{'a': 100, 'b': 200}`, which shows that assigning and adding
+entries both work the same way.
+
+Removing Entries
+----------------
+
+There are two ways to remove entries from a dictionary.  Run the following
+commands:
+
+    :let test = remove(foo, 'a')
+    :unlet foo.b
+    :echo foo
+    :echo test
+
+Vim displays `{}` and `100`.  The `remove` function will remove the entry with
+the given key from the given dictionary and return the removed value.  The
+`unlet` command also removes dictionary entries, but you can't use the value.
+
+You cannot remove nonexistent entries from a dictionary.  Try running this
+command:
+
+    :unlet foo["asdf"]
+
+Vim throws an error.
+
+The choice of `remove` or `unlet` is mostly a matter of personal taste.  If
+pressed I'd recommend using `remove` everywhere because it's more flexible than
+`unlet`.  `remove` can do anything `unlet` can do but the reverse isn't true, so
+you can always be consistent if you use `remove`.
+
+Dictionary Functions
+--------------------
+
+Like lists, Vim has a number of built-in functions for working with
+dictionaries.  Run the following command:
+
+    :echom get({'a': 100}, 'a', 'default')
+    :echom get({'a': 100}, 'b', 'default')
+
+Vim displays `100` and `default`, just like the `get` function for lists.
+
+You can also check if a given key is present in a given dictionary.  Run this
+commands:
+
+    :echom has_key({'a': 100}, 'a')
+    :echom has_key({'a': 100}, 'b')
+
+Vim displays `1` and `0`.  Remember that Vimscript treats `0` as falsy and any
+other number as truthy.
+
+You can pull the key-value pairs out of a dictionary with `items`.  Run this
+command:
+
+    :echo items({'a': 100, 'b': 200})
+
+Vim will display a nested list that looks something like `[['a', 100], ['b',
+200]]`.  As far as I can tell Vimscript dictionaries are *not* guaranteed to be
+ordered, so don't expect that the items you get out of an `items` call will be
+in a specific order!
+
+You can get just the keys or just the values with the `keys` and `values`
+functions.  They work as expected -- look them up.
+
+Exercises
+---------
+
+Read `:help Dictionary`.  All of it.  Notice the capital "D".
+
+Read `:help get()`.
+
+Read `:help has_key()`.
+
+Read `:help items()`.
+
+Read `:help keys()`.
+
+Read `:help values()`.
--- a/outline.org	Wed Oct 26 00:36:40 2011 -0400
+++ b/outline.org	Wed Oct 26 01:17:40 2011 -0400
@@ -33,8 +33,8 @@
 ** DONE basic regexes
 ** DONE Case Study: GrepMotion
 ** DONE lists
-** TODO looping
-** TODO dictionaries
+** DONE looping
+** DONE dictionaries
 ** TODO advanced regexes
 ** TODO paths
 ** TODO exceptions