Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: gh-pages
Fetching contributors…

Cannot retrieve contributors at this time

241 lines (232 sloc) 8.211 kb
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>CopyCat - Fold / Merge</title>
<link rel="stylesheet" type="text/css" href="vendor/highlight/styles/school_book.css" media="screen" />
<script src="vendor/showdown/showdown.js"></script>
<script src="vendor/highlight/highlight.pack.js"></script>
<script src="vendor/jquery/jquery-1.4.2.js"></script>
<script src="vendor/underscore/underscore.js"></script>
<!-- script src="http://bitbucket.org/JustinLove/es5/raw/c6103eab597c/es5.js"></script -->
<!-- script src="http://vice-versa.googlecode.com/files/vice-versa.0.1.4b.min.js"></script -->
<script src="vendor/persevere/global-es5.js"></script>
<script src="vendor/jaysyncunit/jaysyncunit.js"></script>
<script src="vendor/pure/pure.js"></script>
<script src="vendor/inflection-js/inflection.js"></script>
<style>
.contacts div, .contacts span, .contacts ul, .contacts li {
margin: 5px;
padding: 5px;
width: 300px;
}
.contacts div {
border: 2px solid black;
}
.contacts span {
border: 1px solid blue;
}
.contacts ul {
border: 2px solid orange;
}
.contacts li {
border: 1px solid green;
}
</style>
</head>
<body>
Resursively fold a collection of JavaScript hashes into a singular instance with all possible properties of any instance.
<div id="doc">
"use strict";
(function () {
var fixture = {
"friends" : [
{
"first" : "Jamshid",
"last" : "Mavandi",
"accounts" : {
"gmail" : "mvndaai",
"facebook" : "mvndaai"
},
"interests" : {
"tv shows" : [
"Julian Smith"
]
}
},
{
"first" : "Brianna",
"middle" : "Marie",
"last" : "Oviatt",
"accounts" : {
"cakewrecks" : "twilight",
"vark" : "twilight"
},
"interests" : {
"music" : [
"Death Cab for Bootie",
"Sunday Night fever"
]
}
},
{
"first" : "AJ",
"last" : "ONeal",
"accounts" : {
"twitter" : "#coolaj86",
"email" : "coolaj86",
"aim" : "coolaj1986",
"linkedin" : "coolaj86",
"phone" : "317-426-5555",
"facebook" : "coolaj86"
},
"interests" : {
"movies" : [
"Star Wars Trilogy",
"Spiderman",
"The princess bride"
]
}
}
]
};
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length')) &&
typeof value.splice === 'function') {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
} // Thanks to Crockford
/**
* This assumes a 'sane' data structure.
* * No mixing of set types in arrays - strings XOR (similar) objects
* * No nested arrays - objects make this a mute point. You can always easily describe an array
* * Only like objects in arrays (books, movies, music - not books, toothbrush, tyranasaur)
* * Identical keys of similar objects are assumed to be of the same type
*
* There is no reason that arrays should be nested in javascript
* Nor is there any reason to create a bag of unrelated objects.
*
* It does make sense that if a collection holds similar items
* such as books, movies, and music, that all elements are merged
* for the sake of the template
*
* Since it also makes sense that many elements are undefined on
* any particular instance, this will not attempt to duck-type
* the contents of your collection.
*
*/
function merge_json(fixture, other) {
// figure out what to do with this fixture and other
if ('undefined' === typeOf(fixture)) {
return other; // Gotcha: assigning 'undefined' to an object deletes the key!
} else if ('string' === typeOf(fixture)) {
return string2single(fixture, other);
} else if ('array' === typeOf(fixture)) {
return array2single(fixture, other);
} else if ('object' === typeOf(fixture)) {
return object2single(fixture, other);
} else if ('function' === typeOf(fixture)) {
alert("functions are not supported");
return;
} else {
alert("some weird crap happened: " + typeOf(fixture));
return;
}
// strings are easy - this is where we just throw away values
function string2single(s1, s2) {
return s1 || s2;
}
// put each item in each array through the merge
// then merge all items into one array
function array2single(a1, a2) {
var a = [];
a1 = a1 || [];
a2 = a2 || [];
if ('array' !== typeOf(a1) || 'array' !== typeOf(a2)) {
alert('craptastic! expected array');
}
while (0 !== a1.length) {
a.push(merge_json(a1.pop()));
}
while (0 !== a2.length) {
a.push(merge_json(a2.pop()));
}
while (a.length > 1) {
a1 = a.pop();
a2 = a.pop();
a.push(merge_json(a1, a2));
}
return a;
}
// put each member through the merge
// merge both objects
function object2single(o1, o2) {
var o = {};
// Make sure we can call keys
o1 = o1 || {};
o2 = o2 || {};
if ('object' !== typeOf(o1) || 'object' !== typeOf(o2)) {
alert('craptastic! expected object');
}
// Join the keys of both objects into one array, then merge
union_str_arr(Object.keys(o1), Object.keys(o2)).forEach(function (key, i, arr) {
o1[key] = merge_json(o1[key]);
o2[key] = merge_json(o2[key]);
o[key] = merge_json(o1[key], o2[key]); // || o1[key] || o2[key];
//alert("test: " + JSON.stringify(o[key]));
});
return o;
}
// union two string arrays into 1
function union_str_arr(ka1, ka2) {
var o = {};
if ('undefined' === typeOf(ka1) || 'undefined' === typeOf(ka2)) {
return ka1 || ka2;
}
ka1.forEach(function (key, i, arr) {
o[key] = "";
});
ka2.forEach(function (key, i, arr) {
o[key] = "";
});
return Object.keys(o);
}
}
var fixture1 = "simple string";
var fixture2 = ["array", "of", "strings"];
var fixture3 = {"a": "object", "b": "of", "c": "strings"};
var fixture4 = [{"a": "array", "b": "of", "c": "objects"},{"c": "of", "d": "strings"}];
var fixture5 = {"a": ["object", "of"], "b": ["arrays", "of", "strings"]};
//setTimeout(function () {
var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(JSON.stringify(merge_json(fixture)),null,'\t'));
document.body.insertBefore(pre, document.body.firstChild);
//},10000);
}());
</div>
</body>
<script>
"use strict";
(function (doc) {
var showdown = new Showdown.converter(),
body = doc.getElementById('doc'),
markdown,
html;
eval($('#doc').text());
markdown = body.innerHTML;
html = showdown.makeHtml(markdown);
body.innerHTML = html;
hljs.initHighlightingOnLoad();
}(window.document));
</script>
</html>
Jump to Line
Something went wrong with that request. Please try again.