<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Derek Enos</title>
    <description>The latest articles on DEV Community by Derek Enos (@derekenos).</description>
    <link>https://dev.to/derekenos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F163503%2Fc0b9ccc7-ae15-4daf-b06e-8f0d0fa87dbc.jpeg</url>
      <title>DEV Community: Derek Enos</title>
      <link>https://dev.to/derekenos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/derekenos"/>
    <language>en</language>
    <item>
      <title>Predilection for Predicates</title>
      <dc:creator>Derek Enos</dc:creator>
      <pubDate>Wed, 08 Sep 2021 13:34:48 +0000</pubDate>
      <link>https://dev.to/derekenos/predilection-for-predicates-3ji3</link>
      <guid>https://dev.to/derekenos/predilection-for-predicates-3ji3</guid>
      <description>&lt;p&gt;I recently wanted to query arrays of Javascript objects using a declarative syntax and happily took the opportunity to write some small functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Predicates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  EQ (is equal to)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const EQ = x =&amp;gt; y =&amp;gt; x === y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For anyone unfamiliar with ES6 arrow functions:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EQ&lt;/code&gt; is a function that accepts one argument (&lt;code&gt;x&lt;/code&gt;) that returns another function that accepts one argument (&lt;code&gt;y&lt;/code&gt;) which returns the result of evaluating &lt;code&gt;x === y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the equivalent standard &lt;code&gt;function&lt;/code&gt; def:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function EQ (x) {
  return function (y) {
    return x === y
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IN (is included in)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const IN = (...xs) =&amp;gt; x =&amp;gt; xs.includes(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;IN&lt;/code&gt; is a function that accepts one or more arguments collected into an array (&lt;code&gt;xs&lt;/code&gt;) that returns another function that accepts one argument (&lt;code&gt;x&lt;/code&gt;) which returns the result of evaluating &lt;code&gt;xs.includes(x)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logical Operators
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const NOT = pred =&amp;gt; x =&amp;gt; !pred(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const AND = (...preds) =&amp;gt; x =&amp;gt; preds.reduce((acc, pred) =&amp;gt; acc &amp;amp;&amp;amp; pred(x), true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const OR = (...preds) =&amp;gt; x =&amp;gt; preds.reduce((acc, pred) =&amp;gt; acc || pred(x), false)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Doing Stuff
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Filtering Scalar Arrays
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data = [ 1, 2, 1, 1, 3, 2, 2, 2 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Get All the &lt;code&gt;1&lt;/code&gt;s
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt; data.filter(EQ(1))
Array(3) [ 1, 1, 1 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Get All the &lt;code&gt;1&lt;/code&gt;s and &lt;code&gt;2&lt;/code&gt;s
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt; data.filter(IN(1, 2))
Array(7) [ 1, 2, 1, 1, 2, 2, 2 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt; data.filter(OR(EQ(1), EQ(2)))
Array(7) [ 1, 2, 1, 1, 2, 2, 2 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Filtering Arrays of Objects
&lt;/h3&gt;

&lt;p&gt;The above &lt;code&gt;EQ&lt;/code&gt; and &lt;code&gt;IN&lt;/code&gt; predicate functions work great with scalar values (i.e. numbers, booleans, etc), but I needed something that works on objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const OBJ = spec =&amp;gt; obj =&amp;gt; Object.entries(spec).reduce((acc, [k, pred]) =&amp;gt; acc &amp;amp;&amp;amp; pred(obj[k]), true)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;OBJ&lt;/code&gt; accepts an object-type &lt;code&gt;spec&lt;/code&gt; argument that maps key names to predicates.&lt;br&gt;
For example, a &lt;code&gt;spec&lt;/code&gt; value of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ isAdmin: EQ(true), active: EQ(true) }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would match objects with &lt;code&gt;isAdmin = true&lt;/code&gt; AND &lt;code&gt;active = true&lt;/code&gt;. For performing logical ops other than &lt;code&gt;AND&lt;/code&gt;, you can specify them separately and wrap them appropriately. For example, to do an &lt;code&gt;OR&lt;/code&gt; query on these same property values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OR( OBJ({ isAdmin: EQ(true) }), OBJ({ active: EQ(true) }) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better may be to create an &lt;code&gt;OBJ_OR&lt;/code&gt; or something but...moving on&lt;/p&gt;

&lt;h4&gt;
  
  
  Get some legit-looking data from &lt;a href="https://jsonplaceholder.typicode.com/"&gt;JSONPlaceholder&lt;/a&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Todos = await (await fetch("https://jsonplaceholder.typicode.com/todos")).json()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned array looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  },
  ...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Find all uncompleted Todos from Users &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt; Todos.filter(OBJ({userId: IN(1, 2), completed: EQ(false)}))
Array(21) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizations omitted in favor of simplicity
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Short-circuit &lt;code&gt;AND&lt;/code&gt; and &lt;code&gt;OR&lt;/code&gt; on first &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;true&lt;/code&gt; respectively instead of iterating over the entire array of object entries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support implicit &lt;code&gt;EQ&lt;/code&gt; for non-predicate-function object spec values, e.g. &lt;code&gt;{ isAdmin: true }&lt;/code&gt; would be interpreted as &lt;code&gt;{ isAdmin: EQ(true) }&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>functional</category>
    </item>
    <item>
      <title>No &amp;lt;head&amp;gt;, no &amp;lt;body&amp;gt;, no problem?</title>
      <dc:creator>Derek Enos</dc:creator>
      <pubDate>Mon, 01 Mar 2021 16:02:12 +0000</pubDate>
      <link>https://dev.to/derekenos/no-lt-head-gt-no-lt-body-gt-no-problem-1lfc</link>
      <guid>https://dev.to/derekenos/no-lt-head-gt-no-lt-body-gt-no-problem-1lfc</guid>
      <description>&lt;p&gt;I was surprised today when I discovered that the HTML response from &lt;a href="https://twitter.com"&gt;https://twitter.com&lt;/a&gt; does not include a &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag (or &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; for that matter), though does include tags (e.g. &lt;code&gt;&amp;lt;meta charset&amp;gt;&lt;/code&gt;) that are only valid as children of &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Today I learned that this is ok.&lt;/p&gt;

&lt;p&gt;Per the &lt;a href="https://html.spec.whatwg.org/multipage/semantics.html#the-head-element"&gt;HTML spec&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A head element's start tag can be omitted if the element is empty, or if the first thing inside the head element is an element.&lt;/p&gt;

&lt;p&gt;A head element's end tag can be omitted if the head element is not immediately followed by ASCII whitespace or a comment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similar applies to &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;, see: &lt;a href="https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-omission"&gt;https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-omission&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://google.github.io/styleguide/htmlcssguide.html"&gt;Google HTML/CSS Style Guide&lt;/a&gt; even &lt;a href="https://google.github.io/styleguide/htmlcssguide.html#Optional_Tags"&gt;recommends omitting all optional tags&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/SXqw0Vpql4sHX9pCl4/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/SXqw0Vpql4sHX9pCl4/giphy.gif" alt="the more you know animation"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>psa</category>
    </item>
    <item>
      <title>Python Charming with Toolz</title>
      <dc:creator>Derek Enos</dc:creator>
      <pubDate>Sat, 18 May 2019 19:53:27 +0000</pubDate>
      <link>https://dev.to/derekenos/python-charming-with-toolz-4bf2</link>
      <guid>https://dev.to/derekenos/python-charming-with-toolz-4bf2</guid>
      <description>&lt;p&gt;&lt;a href="https://toolz.readthedocs.io/en/latest/index.html"&gt;Toolz&lt;/a&gt; is an extremely useful collection of utility functions that can help you do things that you do all the time, but more explicitly, and often with less code.&lt;/p&gt;

&lt;p&gt;I'm going to highlight a few of the functions that I use the most, but there are many others, and they're all solid gold.&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a new &lt;code&gt;dict&lt;/code&gt; from an existing &lt;code&gt;dict&lt;/code&gt; with some items excluded
&lt;/h1&gt;

&lt;p&gt;Given an original &lt;code&gt;dict&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;original = {
    'A': 1,
    'B': 2,
    'C': 3,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Filtering items by key
&lt;/h2&gt;

&lt;p&gt;To create a new &lt;code&gt;dict&lt;/code&gt; from &lt;code&gt;original&lt;/code&gt; while excluding the item with &lt;code&gt;key='C'&lt;/code&gt;, without &lt;code&gt;toolz&lt;/code&gt;, I'd probably do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new = {
    k: v
    for k, v in original.items()
    if k != 'C'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.keyfilter"&gt;dicttoolz.keyfilter&lt;/a&gt;, this becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new = keyfilter(lambda k: k != 'C', original)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I really love about this &lt;code&gt;keyfilter&lt;/code&gt; solution, aside from being more concise, functional, etc., is that its name clearly tells you what's going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering items by value
&lt;/h2&gt;

&lt;p&gt;Given a helper function called &lt;code&gt;is_even&lt;/code&gt; that returns a &lt;code&gt;bool&lt;/code&gt; indicating whether the single numeric argument is even:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;is_even = lambda x: x % 2 == 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, as not a &lt;code&gt;lambda&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def is_even(x):
    return x % 2 == 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a new &lt;code&gt;dict&lt;/code&gt; from &lt;code&gt;original&lt;/code&gt; while including only the even values, without &lt;code&gt;toolz&lt;/code&gt;, I'd probably do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new = {
    k: v
    for k, v in original.items()
    if is_even(v)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.valfilter"&gt;dicttoolz.valfilter&lt;/a&gt;, this becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new = valfilter(is_even, original)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  For a single key, get the value from each &lt;code&gt;dict&lt;/code&gt; in a &lt;code&gt;list&lt;/code&gt; of &lt;code&gt;dict&lt;/code&gt;s
&lt;/h1&gt;

&lt;p&gt;Given a list of &lt;code&gt;dict&lt;/code&gt;s representing users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = [
    { 'name': 'User A',
      'age': 30,
    }, 
    { 'name': 'User B',
      'age': 32,
    }, 
    { 'name': 'User C',
      'age': 41,
    }, 
    { 'name': 'User D',
      'age': 43,
    }, 
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get just the ages, without &lt;code&gt;toolz&lt;/code&gt;, I'd do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ages = [ user['age'] for user in users ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.itertoolz.pluck"&gt;itertoolz.pluck&lt;/a&gt;, this becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ages = pluck('age', users)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that this ^ (like some other &lt;code&gt;toolz&lt;/code&gt; functions) actually returns a &lt;a href="https://wiki.python.org/moin/Generators"&gt;generator&lt;/a&gt;-type &lt;code&gt;itertools.imap&lt;/code&gt; object, which is fine if you're going to iterate over it, but if you want to index into it like &lt;code&gt;ages[0]&lt;/code&gt;, you'll need to convert it to a list (or tuple):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; ages[0]
TypeError: 'itertools.imap' object has no attribute '__getitem__'

&amp;gt;&amp;gt;&amp;gt; ages = list(pluck('age', users))
&amp;gt;&amp;gt;&amp;gt; ages[0]
30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also &lt;code&gt;pluck&lt;/code&gt; multiple keys at once by specifying them as a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;age_name_pairs = pluck(['age', 'name'], users)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; list(age_name_pairs)
[(30, 'User A'), (32, 'User B'), (41, 'User C'), (43, 'User D')]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Group a &lt;code&gt;list&lt;/code&gt; of &lt;code&gt;dict&lt;/code&gt;s by some criteria
&lt;/h1&gt;

&lt;p&gt;Given the same list of user &lt;code&gt;dict&lt;/code&gt;s as before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;users = [
    { 'name': 'User A',
      'age': 30,
    }, 
    { 'name': 'User B',
      'age': 32,
    }, 
    { 'name': 'User C',
      'age': 41,
    }, 
    { 'name': 'User D',
      'age': 43,
    }, 
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I wanted to group the users into decade-resolution age groups (i.e. 30s, 40s, etc.), without &lt;code&gt;toolz&lt;/code&gt; maybe I'd do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;age_decade_users_map = defaultdict(list)
for user in users:
    age_decade = int(user['age'] / 10) * 10
    age_decade_users_map[age_decade].append(user)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; dict(age_decade_users_map)
{30: [{'age': 30, 'name': 'User A'}, {'age': 32, 'name': 'User B'}],
 40: [{'age': 41, 'name': 'User C'}, {'age': 43, 'name': 'User D'}]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.itertoolz.groupby"&gt;itertoolz.groupby&lt;/a&gt;, this can be accomplished with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;age_decade_users_map = groupby(
    lambda user: int(user['age'] / 10) * 10,
    users
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Honorable mention goes to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.itertoolz.first"&gt;itertoolz.first&lt;/a&gt; - get the first element from an iterable (even &lt;code&gt;set&lt;/code&gt;s!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.itertoolz.partition_all"&gt;itertoolz.partitional_all&lt;/a&gt; - split an iterable into tuples of a specified max length&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.assoc"&gt;dicttoolz.assoc&lt;/a&gt; - get a copy of a dict with a specified item added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.dissoc"&gt;dicttoolz.dissoc&lt;/a&gt; - get a copy of a dict with specified keys removed (similar in function to my &lt;code&gt;keyfilter&lt;/code&gt; example but a better way to do it)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.get_in"&gt;dicttoolz.get_in&lt;/a&gt; - like &lt;code&gt;dict.get()&lt;/code&gt; but with support for multi-depth keys, e.g. &lt;code&gt;get_in(['a', 'b'], {'a': {'b': 1}}) = 1&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy &lt;code&gt;toolz&lt;/code&gt;ing!&lt;/p&gt;

</description>
      <category>python</category>
      <category>toolz</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
