Flash as3 How do I remove duplicates in an array?

2019-01-19 21:04发布

Hi I just have an array of names (strings) in flash, and I want to make sure that any duplicates from the array are removed, or at least that a function is performed only once per reocurring value in the array.

9条回答
做个烂人
2楼-- · 2019-01-19 21:23

Here's another way to do it, possibly a little nicer to look at:

var removeList:Array = [];

// loop over every item in the original array
for each (var item:* in array) {
    // loop over every item again, checking for duplicates
    for each (var other:* in array) {
        // if two items that aren't the same item are equal and `other` doesn't
        // exist in the remove list, then cache it for later removal.
        if (item == other && item !== other && removeList.indexOf(other) == -1)
            removeList.push(other);
    }
}

// next, loop over the cached remove list and remove 'selected' items for removal
for each (var remove:* in removeList) 
    array.splice(array.indexOf(remove), 1);

This probably isn't the most performant way of doing it, @prototypical's method is probably much more efficient, but it's the theory that you asked for :)

查看更多
【Aperson】
3楼-- · 2019-01-19 21:23

Here is a more elegant way of removing duplicates:

var items:Vector.<String> = Vector.<String>(['tortoise', 'cat', 'dog', 'bunny', 'dog', 'cat', 'bunny', 'lion']);

var uniqueItems:Vector.<String> = items.filter(function(item:String, index:int, vector:Vector.<String>):Boolean {
    return index==0?true:(vector.lastIndexOf(item, index-1) == -1);
});

Same approach for an array:

var items:Array = ['tortoise', 'cat', 'dog', 'bunny', 'dog', 'cat', 'bunny', 'lion'];

var uniqueItems:Array = items.filter(function(item:String, index:int, array:Array):Boolean {
        return index==0?true:(array.lastIndexOf(item, index-1) == -1);
    });
查看更多
Lonely孤独者°
4楼-- · 2019-01-19 21:29

Good answers!

I've checked a few of them, and have worse results in contrast to my. It's quite simple:

const origin: Vector.<String> = Vector.<String>(["a", "c", "d", "c", "b", "a", "e", "b", "a"]);

function getUniqueVector(origin: Vector.<String>): Vector.<String> {
    const n: uint = origin.length;
    var res: Vector.<String> = new Vector.<String>();
    var i: int = 0;

    while(i < n) {
        var el: String = origin[i];
        if(res.indexOf(el) == -1) res.push(el);
        i += 1;
    }

    return res;
}

trace(getUniqueVector(origin)); // unique elements vector

Statistics with my data:

Dict approach: 8946ms, 8718ms, 8936ms

Obj approach: 8800ms, 8809ms, 8769ms

My old approach: 8723ms, 8599ms, 8700ms

This approach: 6771ms, 6867ms, 6706ms

查看更多
聊天终结者
5楼-- · 2019-01-19 21:30

I voted for Adam's option, but then I found this, and it looks to me this could be better performance wise still?

  for (var i:uint = array.length; i > 0; i--){
     if (array.indexOf(array[i-1]) != i-1){
        array.splice(i-1,1);
     }
  }     

The idea here is that you loop backwards through the array, and since indexOf gives you the first occurring index, you can check the found index with the current index(i) and remove if not the same.

查看更多
贪生不怕死
6楼-- · 2019-01-19 21:30

would @prototypical s response not give issues if the sourceArray[i] matches sourceArray[j] more than once because the length of sourceArray would be shorter if an element has been .splice()d out of it?

I've rewritten this method to count from the end so that this doesn't happen

for (var i:int = sourceArray.length - 2; i >= 0; --i) 
{
    for (var j:int = sourceArray.length - 1; j > i; --j)
    {
        trace(i, j);
        if (sourceArray[j] === sourceArray[i]) sourceArray.splice(j, 1);
    }
}
查看更多
Rolldiameter
7楼-- · 2019-01-19 21:39

More cat skinning:

var a:Array = ["Tom", "John", "Susan", "Marie", "Tom", "John", "Tom", "Eva"];
a.sort();
var i:int = 0;
while(i < a.length) {
    while(i < a.length+1 && a[i] == a[i+1]) {
        a.splice(i, 1);
    }
    i++;
}
查看更多
登录 后发表回答