ActionScript 3 Remove duplicates in an array

April 17, 2008 by jared 

function fRemoveDup(ac:Array) : void
{
    var i, j : int;
    for (i = 0; i < ac.length - 1; i++)
        for (j = i + 1; j < ac.length; j++)
            if (ac[i] === ac[j])
                ac.splice(j, 1);
}

Then use fRemoveDup(arrayHere) to clear any duplicates.

Click here to download sample.

Comments

18 Responses to “ActionScript 3 Remove duplicates in an array”

  1. webdev.andrei on April 23rd, 2008 5:41 am

    Nice algorithm but is not working as it should. Try to use it with “aabbccaaaaddaaeeff” which should be transformed to “abcdef“. That is because when you do splice on the array you are looping the end condition of the loop changes because the length changes and also the position pointer inside the array changes. Everything is just getting messed up. More on this you can find in this two article:
    http://www.flexer.info/2008/03/11/remove-duplicate-chars-from-a-string/
    http://www.flexer.info/2008/04/23/comparison-remove-duplicate-chars-from-a-string-via-array-and-regexp/

  2. Quince on May 26th, 2008 11:12 pm

    actually it is working perfect.

    It is looking for duplicates in an array
    as in
    ac[0] = “a”;
    ac[1] = “b”;
    ac[2] = “a”;

    ac[2] will be sliced from the array. An important thing to note is the order of the two loops.

    the first loop starts with 0 and allows the second loop to go through before the first loop goes to 1. this means the second of the duplicate entries will always be deleted not the first. switching this line of code

    ac.splice(j, 1);

    to

    ac.splice(i, 1);
    j = ac.length;

    will make the loops delete the first entry of the duplicates.

    I’ve never used the syntax “===” still works though I’ve always used “==” for equals to. The equals to already made the shecker case sensitive.

    Well done!

  3. webdev.andrei on May 27th, 2008 12:20 am

    Lets take your example:
    ac[0] = “a”;
    ac[1] = “b”;
    ac[2] = “a”;
    ac[3] = “a”;
    ac[4] = “a”;
    ac[5] = “c”;
    With your loops it will go like this:
    1) finds ac[2] (var j=2) and removes it, so the array will be:
    ac[0] = “a”;
    ac[1] = “b”;
    ac[2] = “a”;
    ac[3] = “a”;
    ac[4] = “c”;
    Although the element with the index = 2 is removed the whole array is re-indexed.
    2) in the next step j variable will be 3 so ac[3] will be removed leaving ac[2] which is also an “a” in its place. The array will be:
    ac[0] = “a”;
    ac[1] = “b”;
    ac[2] = “a”;
    ac[4] = “c”;
    3) next step j will be 4… and so on

    This is my point of view and thanks for comment.

  4. jared on May 27th, 2008 5:48 am

    cheers guys, I think both of you are right. I simply provided this piece of code here because

    1) I had trouble searching when I needed it.
    2) It worked for me in my situation
    3) so I could easily find it when I needed it

    and if it doesn’t work for you, I guess you just gotta keep on searching. thanks for the comments.

    andrei if you have a example fla file you’d wish to attach feel free to let me know and I’ll put it here.

  5. Quince on May 27th, 2008 8:09 am

    I see what you are talking about webdev you are right. it does error. on the third I found. The array number is changed with slice so the numbers of the array values are 0,1,2,3 not 0,1,2,4

    check out this code it fixes that issue. I left the traces in there for ya :)

    function removeDup(ac:Array):void {
    var deleted:Boolean = false;
    for (var i:Number = 0; i < ac.length – 1; i++) {
    for (var j:Number = i + 1; j < ac.length; j++) {
    if (ac[i] === ac[j]) {
    ac.splice(j, 1);
    deleted = true;
    }
    }
    }
    if(deleted == true){
    removeDup(ac);
    }
    trace(” -0-” + String(ac[0]));
    trace(” -1-” + String(ac[1]));
    trace(” -2-” + String(ac[2]));
    trace(” -3-” + String(ac[3]));
    }

    removeDup(["a","b","a","a","c"]);

    Thanks webdev, I would definitly use your script for duplicate charactors in strings.

  6. Quince on May 27th, 2008 12:08 pm

    Duh, I see what was going on the if statement and all that stuff is not needed. The problem is only that when the array is sliced at j that j need to minus 1 so that the new array item is veiwed too.

    function removeDup(ac:Array):void {
    for (var i:Number = 0; i < ac.length – 1; i++) {
    for (var j:Number = i + 1; j < ac.length; j++) {
    if (ac[i] === ac[j]) {
    ac.splice(j, 1);
    j–;
    }
    }
    }

    trace(” -0-” + String(ac[0]));
    trace(” -1-” + String(ac[1]));
    trace(” -2-” + String(ac[2]));
    trace(” -3-” + String(ac[3]));
    }

    removeDup(["a","b","a","a","c"]);

    all it really needed was that one line of code
    j–;

    when ou copy this code if you get errors it’s from he formating on the quotes use a quick find and replace on them.

    Thanks!

  7. Quince on May 27th, 2008 12:10 pm

    that line of code should be jMinusMinus the second – got taken out by the blog. j – - ;

  8. Brian on June 9th, 2008 4:48 am

    This works too.

    tempArray.sort(Array.NUMERIC);
    for (i=tempArray.length; i>0; i–) {
    if (tempArray[i] == tempArray[i-1]) {
    tempArray.splice(i, 1);
    }
    }

  9. brian on October 24th, 2008 3:40 pm

    don’t forget closures in as 3.

    var is_unique:Function = function (item:*, index:int, array:Array):Boolean {
    return array.indexOf(item,index + 1) == -1;
    };

    var array = [1,2,1,3,2,3];
    trace(array.filter(is_unique));

  10. mauro on January 4th, 2009 6:43 am

    Sorry guys, I am interested in using this code, but which one is best for checking duplicates in matter of emails?

    The array to be a list of emails.

    I have done a script(*) to get rid of almost every dirt from copy and paste from CSV, XLS, Outlook, and other common tools.

    Now I would like to get rid of duplicates!

    (*)Here is the source code:
    http://www.vacanzecroate.com/careless/email/ciclo_CommaEmails_fromTAB.html

  11. Trickmaster on March 24th, 2009 12:43 pm

    Hey thanks a bunch! i tried this code yesterday didn’t work since I had 4 same values in my array, and it only got rid of 2 of them. Then I looked at Quince’s comment today and I retried the code and it worked like a charm!

    Thanks a bunch man

  12. bubbleboy on May 14th, 2009 11:09 am

    just what i was looking for! thanks a lot!

  13. Xavier Laumonier on June 3rd, 2009 12:48 am

    Hi !

    Good function, but it should be :

    var length:int = ac.length
    for (i = 0; i < length – 1; i++)
    for (j = i + 1; j < length ; j++)

    it will be much more optimized, because the length of the array is computed one time in this version, but in your version, the length of the array is computed ( 2 * array.length – 1 ) times..

  14. Tim on July 20th, 2009 11:06 pm

    This is the version I just made up:

    array.forEach( removeDups );
    function removeDups( value:*, index:int, arr:Array):void {
    for( var i:Number = 0; i < arr.length; i++ ) if( i != index ) if( value === arr[i] ) arr.splice( i, 1 );
    }

  15. Bruno Fenzl on October 26th, 2009 2:52 am

    @Brian
    your code is simple and very efficient. Great!!!! thanks.

    @all
    Thanks for the wonderful examples of logic.

  16. Matthieu Chavigny on December 17th, 2009 8:53 pm

    public static function unique(a:Array):Array
    {
    var n:Array = new Array();
    for each(var e in a) {
    var o:Boolean = false;
    for each(var ne in n) if (ne == e) o=true;
    if(!o) n.push(e);
    }
    return n;
    }

  17. Martin Burke on January 22nd, 2010 9:19 pm

    I was having the same problem, where if I had something repeated more than once, only 1 got removed. This can simple be fixe dby replacing the “if” with a “while”.

    With an input of ["a","a","b","b","c","c","a","a","d","d","e","e"];

    if (ac[i] === ac[j])
    gives and output of “a,b,c,a,d,e” (wrong!)

    while (ac[i] === ac[j])
    gives an output of “a,b,c,d,e” (correct!)

    The while forces a check on the new element which has shifted into the position which has just been deleted

  18. Mat G on January 25th, 2010 4:55 am

    Hi guys just though id throw a slightly different approach into the mix..

    function removeDuplicates(array:Array):Array
    {
    var tempRef:Dictionary = new Dictionary();
    var newArray:Array = [];
    var i:int = array.length;
    var tempItem:*;

    while(i–)
    {
    tempItem = array[i]

    if(!tempRef[tempItem])
    {
    tempRef[tempItem] = true;
    newArray.push(tempItem);
    }
    }

    return newArray;
    }

Feel free to leave a comment...
and oh, if you want a pic to show with your comment, go get a gravatar!