title: Parsing structured data in a functional way (e.g. without mutating)
body: <p>Imagine you have the following data in a file:</p>
  
  <pre><code>Group1
    Thing1
    Thing2
  Group2
    Thing1
    Thing2
    Thing3
  Group3
  Group4
    Thing1
  </code></pre>
  
  <p>It's easy to write a "parser" which loops through the file line-by-line, remembering the current <code>Group</code> (in a variable) and then writing all the <code>Thing</code>s to an object, neatly grouped by their respective group:</p>
  
  <pre><code>// Very naive implementation for illustrative purposes only
  let groups = {}
  let currentGroup = null
  data
    .split(/\n/)
    .forEach(entry =&gt; {
      const matches = entry.match(/^(Group\d+)$/)
      if (matches) {
        currentGroup = matches[1]
        groups[currentGroup] = []
      } else {
        groups[currentGroup].push(entry.trim())
      }
    })
  </code></pre>
  
  <p>which gives me:</p>
  
  <pre><code>{
    Group1: [
      'Thing1', 'Thing2'
    ],
    Group2: [
      'Thing1', 'Thing2', 'Thing3'
    ],
    ...
  }
  </code></pre>
  
  <p>What's the best way to achieve this without mutating <code>groups</code> and <code>currentGroup</code>, in a purely functional way? Do I need to take a harder look at <code>Array.reduce</code>, because I've seen some (IMHO rather mind-boggling) use-cases to transform an Array into an Object, or is that not going to help here?</p>