Skip to end of metadata
Go to start of metadata

The this2that library provides utility functions for converting from one object to another

General Functions

transform

transform(<obj>,<sort options> |,<global options>)

ParameterDatatypeRequired
<obj>hash/map or array 
<sort options>hash or array of hashes 
<global options>hash 

<obj> : array or hash of values to be sorted

<sort options> :

  • path : <hash path> to field that is providing the sort value required
  • reverse : <boolean> sort in descending order (default is to sort in ascending order)
  • compare : <string> force sorting to a specific datatype
    • datetime
    • numeric
    • string
  • format : <string> a strptime compatible string containing format rules for non-ISO8601 datetime strings
<global options> : parameters applied after the <obj> has been sorted
  • index : <integer> 0-based index of which element of the sorted array to return to the user
  • limit : <integer> number of elements of the sorted array to return
A note on datetime formats.  The sorting algorithm should recognize ISO8601 and common internet and email formats.  The format returned by Twitter is slightly different and requires a format string to allow the sort mechanism to parse correctly. The Twitter format string is demonstrated in examples below.
Providing a hash as the obj, will return an array of the hash keys sorted by the provided parameters (sort by reference)


Examples

myHash = {
	"0001" : {
		"type": "donut",
		"name": "Cake",

	},
	"0002" : 	{
		"type": "donut",
		"name": "Raised",
	},
    "0003":	{
		"type": "donut",
		"name": "Old Fashioned",
	},
	"0004" : {
		"type": "muffin",
		"name": "Poppy seed",

	}	
};

sort_opt = {
	'path' : ['name']
};
 
sorted_array = this2that:transform(myHash,sort_opt);  // ["0001", "0003", "0004", "0002"]
Given an array of similar objects such as returned by the twitter user_timeline function, an abbreviated object is shown below

 

myArray = [ {
  'retweet_count' : 360,
  'created_at' : 'Fri Aug 16 21:19:37 +0000 2013',
  'in_reply_to_status_id_str' : undef,
  'contributors' : undef,
  'text' : "RT \@SharylAttkisson: Still waiting for White House to call back to release the White House photos from Benghazi night. I've been asking sin\x{2026}",
  'user' : {
    'id_str' : '13524182',
    'id' : 13524182
  },
  'id' : '368482201631227904',
  'lang' : 'en',
  'geo' : undef,
  'id_str' : '368482201631227904',
  'favorite_count' : 0,
 },
..
]

 

Providing an array as the sorted object will return the entire object entries in sorted order (sort by value)

Simple sort on a field

Sort by number of retweets
sort_opt = {
	'path' : ['retweet_count']
};
 
sorted_array = this2that:transform(myArray,sort_opt);

 

Descending sort

Sort by number of retweets in descending order
sort_opt = {
	'path' : ['retweet_count'],
	'reverse' : 1
};
 
sorted_array = this2that:transform(myArray,sort_opt);

 

Force sort on <field> as a string

Sort by number of retweets in alphabetical order
sort_opt = {
	'path' : ['retweet_count'],
	'compare' : 'string'
};
 
sorted_array = this2that:transform(myArray,sort_opt);

 

Sort on a date field

Sort by number of retweets by date created
sort_opt = {
	'path' : ['created_at'],
	'compare' : 'datetime',
	'format' : '%a %b %d %H:%M:%S %z %Y'
};
 
sorted_array = this2that:transform(myArray,sort_opt);

 

Sort on multiple fields, retweet_count (descending) then favorite_count (ascending)

Sort by number of retweets and favorites
sort_opt = [
	{
	'path' : ['retweet_count'],
	'reverse' : 1
	},
	{
	'path' : ['favorite_count']
	}
 ];

sorted_array = this2that:transform(myArray,sort_opt);

 

Skip the first 5 entries

Sort by number of retweets
sort_opt = {
	'path' : ['retweet_count']
};
 
global_opt = {
	'index' : 4
};
 
sorted_array = this2that:transform(myArray,sort_opt,global_opt);

 

Skip 5, only return 7 entries

Sort by number of retweets
sort_opt = {
	'path' : ['retweet_count']
};
 
global_opt = {
	'index' : 4,
	'limit' : 7
};
 
sorted_array = this2that:transform(myArray,sort_opt,global_opt);

 

Sort the values of a hash

Sort by number of retweets in descending order
sort_opt = {
	'path' : ['retweet_count'],
	'reverse' : 1
};
 
sorted_hash_keys = this2that:transform(myHash{['path', 'to', 'keys']},sort_opt);

xml2json

xml2json(<string>|,<map>) - convert a string of XML to JSON

  jstr = this2that:xml2json("<foo type=\"bar\">XML element</foo>");
result: {  "@encoding":"UTF-8",
  "@version":"1.0",
  "foo":{
   "$t":"XML element",
   "@type":"bar"}
}
 

Through optional parameters, some control of the resultant JSON is possible

Given:

<sample_dataset>
        <seed name="Strawberries" type="fruit">
                <harvest_time>4 Hours</harvest_time>
                <cost type="coins">10</cost>
                <xp>1</xp>
        </seed>
</sample_dataset>

With attribute_prefix you can change the attribute prefix from the default '$'

jstr = this2that:xml2json(xmlstring,{
	'attribute_prefix' : '_:_'
});
result: {
  "_O_encoding":"UTF-8",
  "sample_dataset":{
    "seed":{
      "cost":{
        "$t":"10",
        "_O_type":"coins"
      },
      "xp":{
         "$t":"1"
      },
      "_O_name":"Strawberries",
      "harvest_time":{
        "$t":"4 Hours"
      },
      "_O_type":"fruit"
    }
  },
  "_O_version":"1.0"
 }

A similar option is available to change the content key

jstr = this2that:xml2json(xmlstring,{
	'content_key' : '-t-'
});

result: {
  "cost":{
    "-t-":"10",                  
    "@type":"coins"

  } ....
}

Other parameters include

  • empty_elements
  • private_attributes
  • private_elements

Each of these requires an array the fields that you desire to either suppress the value or the entire element

Char

chr

chr(<integer>)

Returns the ascii value of the passed number

myChar = this2that:chr(101);			// 'e'
 
myUnicode = this2that:chr(0x010f);		// '?'

For values beyond 0x0100 in the Unicode chart, you can pass a hex value for a Unicode character and get that character back

ord

ord(<string>)

KRL doesn't distinguish chars from string, so if the string provided has more than one character, only the first character will be processed

myNum = this2that:ord("e");				// 101
 
myUnicode = this2that:ord("?");			// 0x263A

For heaven's sake, if you are cutting and pasting characters between sources and KRL, make sure that your encoding is set to 'UTF-8'.  Many browsers will default to Western (ISO-8859-1) which translates approximately to garbage in the Unicode table.

pack

pack([<integer>, <integer2> .. , <integerN>] );

Returns the ascii value of the passed numbers concatenated into a string

myStr = this2that:pack([101, 102, 103]);			// 'efg'
 

pack is restricted to assembling strings

unpack

unpack(<string>);

Returns an array of ordinal values

myArray = this2that:unpack("hij");			// [104, 105, 106]
 

pack is restricted to assembling strings

 

Base64

string2base64

string2base64(<string>|,<eol>)

Specifying an end-of-line character will format the base64 string into 74 character blocks

b64 = this2that:string2base64("the rain in spain","\n")

Omitting the <eol> character will return an unformatted base64 string

base642string

txt = this2that:base642string("U3VwZXJEdXBlcjogYXNjaWk=")

url2base64

The url-safe base64 conversions use "-" and "_" instead of "+" and "/"

url64 = this2that:url2base64("3+4/7 = 1");

base642url

urltxt = this2that:base642url("Mys0LzcgPSAx");