Skip to content

Instantly share code, notes, and snippets.

@brinchj
Created September 21, 2010 13:37
Show Gist options
  • Select an option

  • Save brinchj/589692 to your computer and use it in GitHub Desktop.

Select an option

Save brinchj/589692 to your computer and use it in GitHub Desktop.
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