Created
September 21, 2010 13:37
-
-
Save brinchj/589692 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Array.prototype.unique = function() { | |
| var OBJ = 'objects_5b299b192302406291224af702b05463'; | |
| var set = {}; | |
| set[OBJ] = {}; | |
| var arr = new Array(); | |
| for(var i = 0; i < this.length; i++) | |
| { | |
| var e = this[i]; | |
| if(typeof(e) == 'object') { | |
| var key = JSON.stringify(e); | |
| if(set[OBJ][key]) continue; | |
| set[OBJ][key] = true; | |
| } else { | |
| if(set[e]) continue; | |
| set[e] = true; | |
| } | |
| arr.push(e); | |
| } | |
| return arr; | |
| }; | |
| //Unique Array of objects, Createde by Allan Ebdrup. | |
| //You may copy & modify it freely as long as this message remains. Licenses: GPL, MIT. | |
| Uia = window.Uia || {}; | |
| Uia.unique = function (a) { | |
| var unusedProperty, i = 0, j, isPropertyUsed = true, | |
| length = a.length, element, aElementCleanup = [], a2 = [], | |
| propertyBag = {}, blnUsePropertyBag, elementProperty; | |
| //find unused property | |
| while (isPropertyUsed) { | |
| unusedProperty = "_^´_" + i; | |
| isPropertyUsed = false; | |
| for (j = 0; j < length && !isPropertyUsed; j++) { | |
| element = a[j]; | |
| if (!Uia.isNull(element) && !Uia.isUndefined(element)) { | |
| isPropertyUsed = !Uia.isUndefined(element[unusedProperty]); | |
| } | |
| } | |
| i++; | |
| } | |
| //remove duplicates | |
| for (i = 0; i < length; i++) { | |
| element = a[i]; | |
| blnUsePropertyBag = true; //for By Value objects | |
| if (Uia.isString(element)) { | |
| elementProperty = "´s" + element; | |
| } else if (Uia.isNumber(element)) { | |
| elementProperty = "´n" + element; | |
| } else if (Uia.isDate(element)) { | |
| elementProperty = "´d" + element.getTime(); | |
| } else if (Uia.isBoolean(element)) { | |
| elementProperty = "´b" + element; | |
| } else if (Uia.isNull(element)) { | |
| elementProperty = "´N"; | |
| } else if (Uia.isUndefined(element)) { | |
| elementProperty = "´U"; | |
| } else { | |
| //By Reference element | |
| blnUsePropertyBag = false; | |
| if (Uia.isUndefined(element[unusedProperty])) { | |
| //element does not have property, therfore we have not seen it before | |
| a2.push(element); | |
| element[unusedProperty] = true; | |
| aElementCleanup.push(element); //for removing property | |
| } | |
| } | |
| if (blnUsePropertyBag) { | |
| if (Uia.isUndefined(propertyBag[elementProperty])) { | |
| //element does not have property, therfore we have not seen it before | |
| a2.push(element); | |
| propertyBag[elementProperty] = true; | |
| } | |
| } | |
| } | |
| //remove property | |
| length = aElementCleanup.length | |
| for (i = 0; i < length; i++) { | |
| delete aElementCleanup[i][unusedProperty]; | |
| } | |
| return a2; | |
| } | |
| Uia.isDate = function (vntTest) { | |
| return vntTest instanceof Date; | |
| } | |
| Uia.isBoolean = function (vntTest) { | |
| return typeof vntTest == 'boolean' || vntTest instanceof Boolean; | |
| } | |
| Uia.isNumber = function (vntTest) { | |
| return (typeof vntTest == 'number' || vntTest instanceof Number) && isFinite(vntTest); | |
| } | |
| Uia.isString = function (vntTest) { | |
| return typeof vntTest == 'string' || vntTest instanceof String; | |
| } | |
| Uia.isNull = function (vntTest) { | |
| return typeof vntTest == 'object' && !vntTest; | |
| } | |
| Uia.isUndefined = function (vntTest) { | |
| return typeof vntTest == 'undefined'; | |
| } | |
| function unique2(array) { | |
| return array.unique(); | |
| } | |
| var dtm = new Date(); | |
| var obj = { a: 0 }; | |
| function double(a) { | |
| var l = a.length; | |
| //first we make some stuff that is the same every time to get duplicates | |
| a[a.length] = dtm; | |
| a[a.length] = obj; | |
| a[a.length] = true; | |
| a[a.length] = false; | |
| a[a.length] = null; | |
| a[a.length] = undefined; | |
| a[a.length] = 2; | |
| a[a.length] = 2.2; | |
| a[a.length] = double; //also test function duplicates | |
| for (var i = 1; i < l; i++) { | |
| a.push({ a: "test" }); | |
| } | |
| return a; | |
| } | |
| function takeTime(a, fnUnique) { | |
| var startTime = (new Date()).getTime(); | |
| var au = fnUnique(a); | |
| var dt = (new Date()).getTime() - startTime; | |
| return { dt: dt, au: au }; | |
| } | |
| var arr, stopSlow; | |
| function test() { | |
| arr = [{ a: "dette" }, "hej", dtm, "hej", dtm, true, true, false, false, null, null, undefined, undefined, 2, 2, { a: "er" }, { a: "en" }, { a: "test" }, { a: "af" }, { a: "unique"}]; | |
| //duplicate some objects | |
| arr[arr.length] = arr[0]; | |
| document.getElementById("output").innerHTML = ""; | |
| //document.getElementById("testButton").disabled = true; | |
| stopSlow = false; | |
| test2(); | |
| } | |
| function test2() { | |
| var o = takeTime(arr, Uia.unique); | |
| var dt = o.dt; | |
| document.getElementById("output").innerHTML += "Allan Ebdrup unique on array of length: " + arr.length + ": Removed " + (arr.length - o.au.length) + " duplicates in <b>" + dt + "ms</b> ± 2ms<br/>"; | |
| if (dt > 1000 || arr.length>400000) { | |
| document.getElementById("output").innerHTML += "<br/>TEST DONE!<br/><br/>"; | |
| //document.getElementById("testButton").value = "Kør test igen"; | |
| //document.getElementById("testButton").disabled = false; | |
| return; | |
| } | |
| if (!stopSlow) { | |
| var o2 = takeTime(arr, unique2); | |
| dt = o2.dt; | |
| document.getElementById("output").innerHTML += "Standard unique on array of length: " + arr.length + ": Removed " + (arr.length - o2.au.length) + " duplicates in <b>" + dt + "ms</b> ± 2ms<br/><br/>"; | |
| if (o2.au.length != o.au.length) { | |
| throw new Error("ERROR!!! Returned arrays not same length"); | |
| } | |
| if (dt >= 1000) { | |
| document.getElementById("output").innerHTML += "STOPPING Standard unique it's taking too long<br/><br/>"; | |
| stopSlow = true; | |
| } | |
| } | |
| arr = double(arr); | |
| document.getElementById("output").scrollIntoView(); | |
| setTimeout(test2, 1); | |
| } | |
| function run() { | |
| test(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment