All Downloads are FREE. Search and download functionalities are using the official Maven repository.

utils.harmony.js Maven / Gradle / Ivy

/*
 * Copyright 2016 Novartis Institutes for BioMedical Research Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
//require.config({
//  baseUrl: "",
//  paths: {
//    lodash:     "file:///utils/lodash.min",
//    JSON:       "file:///utils/json2"
//  }
//});
//
//require(["lodash","JSON"], function(_,JSON) {
(function() {    
  this.expandArrayKeys = function(element, src) {
  	var indices = [];
  	if (/\-/.test(element)) // range
  	{
  		var min = parseInt(element.substring(1, element.indexOf('-')));
  		var max = parseInt(element.substring(element.indexOf('-') + 1));
  		for (var i = min; i <= max; i++) {
  			indices.push(i);
  		}
  	} else if (/\,/.test(element)) // non-contig selection
  	{
  		_.each(element, function(i) {
  			indices.push(i);
  		});
  	} else if (/\*/.test(element)) // all
  	{
  		var min = 0;
  		var max = src.length;
  		for (i = min; i < max; i++) {
  			indices.push(i);
  		}
  	} else {
  		// single array ref in compound key
  	}
  	return indices;
  };
  
  this.mergeArrayKeys = function(elem, elements, matchHash, keyContainer) {
  	var keyCount = keyContainer.length;
  	var matchKeys = _.keys(matchHash);
  	var elementCount = elements.length;
  	var matchHashVals = _.values(matchHash);
  	// pad array with subarray.length == 1
  	// in case matchHash.length == 1 && matchHash[0].length = 1
  	matchHashVals.push([ 0 ]);
  	var maxIter = _.reduce(matchHashVals, function(a, b) {
  		return a.length * b.length;
  	});
  	// iterate over each element of the src key
  	if (elem < elementCount && (keyContainer.length <= maxIter)) {
  		// iterate over all currently stored variations of this src key
  		for (var k = 0; k < keyCount; k++) {
  			var currentKey = keyContainer[k].split(/\./).slice();
  			// is this element in need of expansion?
  			if (_.indexOf(matchKeys, elem.toString()) == -1) // elem is not
  																// stored in
  																// matchKeys
  			{
  				// has element been added to currentKey
  				if (elem >= currentKey.length - 1)
  					currentKey.push(elements[elem]); // simple append
  				// special case for elem == 0
  				else if (elem == 0 && currentKey.length == 1
  						&& currentKey[0] == "")
  					currentKey[0] = elements[elem];
  
  				keyContainer[k] = currentKey.join('.');
  			} else // needs expansion
  			{
  				// get base key
  				currentKey = keyContainer[k].split(/\./).slice(0, elem);
  				// length of expanded key array
  				var currentCount = matchHash[elem].length;
  				// iterate over key-expansion entries
  				for (var n = 0; n < currentCount; n++) {
  					// clone the base key
  					var neoKey = currentKey.slice();
  					// add the array ref to the neoKey
  					neoKey.push('[' + matchHash[elem][n] + ']');
  					// add or replace the key
  					if (n == 0)
  						keyContainer[k] = neoKey.join('.');
  					else
  						keyContainer.push(neoKey.join('.'));
  				}
  			}
  		}
  		// recurse to next elem
  		mergeArrayKeys(++elem, elements, matchHash, keyContainer);
  	}
  };
  
  
  this.harmonize = function(s,h) {
    var src   = this.JSON.parse(s);
    var hm    = this.JSON.parse(h);
    if(!_.isArray(src))
      return this.JSON.stringify(this._harmonize(src,hm));
    else
    {
      var result = [];
      _.each(src,function(o){
        result.push(this._harmonize(o,hm));
      });
      return this.JSON.stringify(result);
    }
  };
  
  this._harmonize = function(src,hm) {
  	var prune = hm.prune; // prune flag
  	var neo   = src; // set neo to src by default
  
  	if (prune) {
  		neo = {}; // only mapped keys will be in result
  	}
  	
  	_.each(_.keys(hm), function(key)             // iterate over hmap
  	{
  		var RX_ARRAY = /(.+)\[([*\d\-,]+)\](.+)?/, // key contains array i.e, x.[*].y
  		RX_IDX  = /\[(\*|\d+[\,-]\d+)\]/,          // index matches
  		srcComp = false,                           // compound key in original
  		k       = [],                              // container for key iteration
  		hmkey   = hm[key],                         // original src key value
  		keyMap  = {};
  
  		if (/.+[.](.+)?/.test(key)) // test for compound key in original
  			srcComp = true;
  
  		if (/.+[.].+/.test(hmkey))  // test for compound key in value
  			neoComp = true;
  
  		// This conditional is all about handling array signifiers in the "src" key.
  
  		if (srcComp && RX_ARRAY.test(key)) // test for array in key
  		{
  			var elements  = key.split(/\./);
  			var matchHash = {};
  
  			// Iterate over all elements of compound key
  			for (var m = 0; m < elements.length; m++) {
  				// If element is array ref, store it's index as a hash key
  				// e.g., k1.[*].k2.[1-4]
  				if (RX_IDX.test(elements[m])) {
  					// e.g., matchHash[1] = [], matchHash[3] = []
  					matchHash[m] = [];
  				}
  			}
  
  			// Iterate over the hash keys and set each hash value
  			// to an array of desired indices from the src object
  			_.each(_.keys(matchHash), function(m) {
  				// e.g., matchHash[1] = [1,2,3,4,5], matchHash[3] = [1,2,3,4]
  				matchHash[m] = expandArrayKeys(elements[m],
  						src[elements[m - 1]]);
  			});
  			k.push(key);
  			// Iterate over the hash and create the expanded keys for processing
  			mergeArrayKeys(0, elements, matchHash, k);
  		} else {
  			k.push(key); // no array ref, just simple key
  		} // end array ref handling
  
  		// map expanded keys et al to neo keys
  		for (var km = 0; km < k.length; km++) {
  			keyMap[k[km]] = key;
  		}
  
  		// process keys into return object
  		_.each(k, function(key) {
  			var neoKey = hmkey,
  			// multiple (>1) src keys point to the same neo key:
  			needsArray = _.filter(_.values(keyMap), function(o) {
  				return o == keyMap[key];
  			}).length > 1;
  
  			if (needsArray) {
  				if (!Array.isArray(neo[neoKey]))
  					neo[neoKey] = [];
  				var val = _.get(src, key);
  				/*
  				 * accounts for mapped keys omitted from nested arrays, i.e.,
  				 * key1[*].keyx mapped would result in null indexs 1,2
  				 * {"key1":[{"keya":"x","keyx":"a"}, {"keya":"y","keyy":"b"},
  				 * {"keya":"z","keyz":"c"}]}
  				 */
  				if (val != null)
  					neo[neoKey].push(val);
  			} else {
  				neo[hm[key]] = _.get(src, key); // set the new key val to the old key val
  			}
  
  			// delete the old key if necessary
  			if (!prune) // !(prune) bc (prune) == only hm keys are present in the 1st place
  			{
  				if (srcComp) {
  					var comp = key.split(/./), j = comp.length - 1;
  					while (j > 0) {
  						// do some compound src key pruning magic here
  						j--;
  					}
  				} else {
  					delete neo[key];
  				}
  			}
  		});
  
  		// explode compound neoKeys
  		_.each(_(_.keys(neo)).filter(function(nk) {
  			return /[.]/.test(nk);
  		}).value(), function(nk) {
  			var kys = nk.split(/\./);
  			var value = neo[nk];
  			var obj = {};
  			for (var i = 0; i < kys.length; i++) {
  				if (i == 0) // first element
  				{
  					value = neo[nk];
  					if (!_.has(neo, kys[i])) // key doesn't exist yet
  					{
  						neo[kys[i]] = obj;
  					} else // key does exist
  					{
  
  					}
  				} else if (i == kys.length - 1) // last element
  				{
  					obj[kys[i]] = value;
  				} else {
  					obj[kys[i + 1]] = {};
  					obj = obj[kys[i + 1]];
  				}
  			}
  			delete neo[nk];
  		});
  	});
  	return neo;
  };
  
  this.flatten = function(s) 
  {
    // convert string to obj
    var src     = this.JSON.parse(s);
    var data    = {};
    var a       = [];
    var result  = "", val = "";
    var maxRows = 0, rows = 0;
    
    // put src into array
    if(!_.isArray(src)) 
    {
      a.push(src);
    }
    else
    {
      a = src.slice();
    }
    // process array
    this._flatten("",a,data);
    
    // create the response string
    var keys = _.keys(data);
    _.each(keys, function(k) {
      rows = data[k].length;
      if(rows > maxRows)
        maxRows = rows;
      result += "\""+k+"\",";
    });
    result = result.slice(0,-1)+"\n";
    
    for(var i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy