From 17d6e4919e881bbf9dc0735d93a28c4d92ef2b75 Mon Sep 17 00:00:00 2001 From: Anton Rissanen Date: Sat, 23 Jun 2012 16:40:46 +0300 Subject: [PATCH] New title: Creating a dictionary Object from an Array --- authors.md | 1 + ...ating-a-dictionary-object-from-an-array.md | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 chapters/arrays/creating-a-dictionary-object-from-an-array.md diff --git a/authors.md b/authors.md index b1eef97..6b21f9b 100644 --- a/authors.md +++ b/authors.md @@ -20,6 +20,7 @@ The following people are totally rad and awesome because they have contributed r * Jeff Pickhardt *pickhardt (at) gmail (dot) com* * Frederic Hemberger * Mike Hatfield *oakraven13@gmail.com* +* [Anton Rissanen](http://github.com/antris) *hello@anton.fi* * ...You! What are you waiting for? Check out the [contributing](/contributing) section and get cracking! # Developers diff --git a/chapters/arrays/creating-a-dictionary-object-from-an-array.md b/chapters/arrays/creating-a-dictionary-object-from-an-array.md new file mode 100644 index 0000000..cf8dd53 --- /dev/null +++ b/chapters/arrays/creating-a-dictionary-object-from-an-array.md @@ -0,0 +1,63 @@ +--- +layout: recipe +title: Creating a dictionary Object from an Array +chapter: Arrays +--- +## Problem + +You have an Array of Objects, such as: + +{% highlight coffeescript %} +cats = [ + { + name: "Bubbles" + age: 1 + }, + { + name: "Sparkle" + favoriteFood: "tuna" + } +] +{% endhighlight %} + +But you want to access it as a dictionary by key, like `cats["Bubbles"]`. + +## Solution + +You need to convert your array into an Object. Use reduce for this. + +{% highlight coffeescript %} +# key = The key by which to index the dictionary +Array::toDict = (key) -> + @reduce ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {} +{% endhighlight %} + +To use this: + +{% highlight coffeescript %} + catsDict = cats.toDict('name') + catsDict["Bubbles"] + # => { age: 1, name: "Bubbles" } +{% endhighlight %} + +## Discussion + +Alternatively, you can use an Array comprehension: + +{% highlight coffeescript %} +Array::toDict = (key) -> + dict = {} + dict[obj[key]] = obj for obj in this when obj[key]? + dict +{% endhighlight %} + +If you use Underscore.js, you can create a mixin: + +{% highlight coffeescript %} +_.mixin toDict: (arr, key) -> + throw new Error('_.toDict takes an Array') unless _.isArray arr + _.reduce arr, ((dict, obj) -> dict[ obj[key] ] = obj if obj[key]?; return dict), {} +catsDict = _.toDict(cats, 'name') +catsDict["Sparkle"] +# => { favoriteFood: "tuna", name: "Sparkle" } +{% endhighlight %} \ No newline at end of file