JSFiddle - React, Tailwind, and code Playground

by Michael Barros

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<pre id="test">Output:</pre>

CSS

#test {
    background: #ffb;
    padding: 10px;
    border: 2px solid #999;
}

JavaScript

/**
 * DataObjectParser
 */
function DataObjectParser($data){
  this._data = $data || {};
}

/**
 * Given a dot deliminated string set will create an object 
 * based on the structure of the string with the desired value
 * 
 * @param {[String} $path  path indicating where value should be placed
 * @param {Mixed} $value   the value desired to be set at the location determined by path
 */
DataObjectParser.prototype.set = function($path, $value) {
  if(!$path || $path==='') return void 0;

  var _self = this;
  var re = /[\w]+|\[\]|([^\[[\w]\]]|["'](.*?)['"])/g;
  // parse $path on dots, and brackets
  var pathList = $path.match(re);
  var parent = this._data;
  var parentKey;
  var grandParent = null;
  var grandParentKey = null;

  var addObj = function($obj, $key, $data) {
    if($key === '[]') {
      $obj.push($data);
    } else {
      $obj[$key] = $data;
    }     
  };
  
  while(pathList.length > 0) {
    parentKey = pathList.shift().replace(/["']/g, '');

    // Number, treat it as an array
    if (!isNaN(+parentKey) || parentKey === "[]") {
      if(!_.isArray(parent)  /* prevent overwritting */ ) {
        parent = [];
        addObj(grandParent, grandParentKey, parent);
      }

    // String, treat it as a key
    } else if (_.isString(parentKey)) {
      if(!_.isObject(parent)) {
        parent = {};
        addObj(grandParent, grandParentKey, parent);
      }
    }
    // Next
    grandParent = parent;
    grandParentKey = parentKey;
    parent = parent[parentKey];
  }

  addObj(grandParent, grandParentKey, $value);
  return this;
};

/**
 * Returns the value defined by the path passed in
 * 
 * @param  {String} $path string leading to a desired value
 * @return {Mixed}        a value in an object 
 */
DataObjectParser.prototype.get = function($path) {
  var data = this._data;
  var regex = /[\w]+|\[\]|([^\[[\w]\]]|["'](.*?)['"])/g;
  //check if $path is truthy
  if (!$path) return void 0;
  //parse $path on dots and brackets
  var paths =...