
In PHP there is a very useful function called array_count_values. It sorts an array by returning a 2 dimensional array consisting of non duplicate elements as keys, and values determined by how many times these elements appeared in the original array.
update 09.10.10
This can be achieved (in AS2 and AS3) in a much simpler manner, using the following function or prototype:
Array.prototype.countValues = function() : Array { var i, j = -1, c, o = {}, r = [], v, n = a.length; for(i = 0;i < n;++i) (c = o[v = a[i]]) ? ++c[1] : r[int(++j)] = o[v] = [v,1]; return r; }
So, for example, an array [“red”,”green”,”blue”,”red”] would be converted into [“red” => 2, “green” =>1, “blue” => 1]. Duplicate elements are removed and the new array indicates how many times each, now unique value occurred in the array.
Unfortunately, Actionscript has no such function built in, so I made one. It is a modification of Senocular’s array.unique() prototype (which you can find in his Actionscript library), however rather than simply returning a unique array, it returns the 2 dimensional array mentioned above.
Array.prototype.countValues = function ()
{
var z, x = this.length, c = false, a = [], d = [];
while (x--)
{
z = 0;
while (z < x)
{
if (this[x] == this[z])
{
c = true;
d.push (this[x]);
break;
}
z++;
}
if (!c) a.push ([this[x], 1]);
else c = false;
}
y = a.length;
while (y--)
{
q = 0;
while (q < d.length)
{
if (a[y][0] == d[q]) a[y][1]++;
q++;
}
}
return a;
};
Example useage:
var myArray:Array = new Array ("the", "cat", "sat", "on", "the", "mat");
var newArray:Array = myArray.countValues ();
trace (newArray);
// Returns [[mat,1],[on,1],[sat,1],[cat,1],[the,2]]
This prototype should work with arrays of objects, though it was designed for simple datatypes such as strings.
Note: This prototype is case sensitive for strings. If you want it to be case insensitive, just modify to, for example:
if (a[y][0].toLowerCase () == d[q].toLowerCase ()) a[y][1]++;
Could you convert this to AS3… I don’t know mush AS2 since I’ve just started learning.
Yes, this would be nice in AS3
I’ve updated the example – this was very old and I now see a much faster and more concise method for achieving this. It will work in AS2 and AS3:
Array.prototype.countValues = function() : Array { var i, j = -1, c, o = {}, r = [], v, n = a.length; for(i = 0;i < n;++i) (c = o[v = a[i]]) ? ++c[1] : r[int(++j)] = o[v] = [v,1]; return r; }Hey thought I might not be using this code, but it did helped me how to use while loops in better way……
Thanks anyways.