Flash as3如何删除数组中的重复项?

时间:2011-05-13 21:13:24

标签: flash actionscript-3 actionscript

嗨我在flash中只有一个名字(字符串)数组,我想确保删除数组中的任何重复项,或者至少在数组中每次重新生成值时只执行一次函数。< / p>

9 个答案:

答案 0 :(得分:18)

很多方面。您可以对数组进行排序并迭代它,忽略与上一次迭代匹配的条目。或者您可以使用indexOf()来搜索重复项。或者您可以对数组进行一次传递,构建一个键入字符串的字典(并忽略已经有条目的键)。

这是字典方式,每个唯一条目的内存成本为1布尔值,当你期望很多欺骗时容易记忆,而且速度很快。如果你有相对较少的欺骗,连续欺骗的排序+剔除可能更有效

import flash.utils.Dictionary;

var array:Array = ["harry","potter","ron","harry","snape","ginny","ron"];
var dict:Dictionary = new Dictionary();

for (var i:int = array.length-1; i>=0; --i)
{
    var str:String = array[i] as String;
    trace(str);
    if (!dict[str])
    {
        dict[str] = true;
    }
    else
    {
        array.splice(i,1);
    }
}

dict = null;


trace(array);

这是一种排序方式,但请注意:这不是保留订单!你没有说这是否重要。但是因为它使用了快速排序,它确实倾向于具有O(N log N)性能加上一次额外的通过,除非你的数据当然是病态的。

var array:Array = ["harry","potter","ron","harry","ron","snape","ginny","ron"];

array.sort();
trace(array);

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


trace(array);

除了没有说明订单是否重要之外,你没有说是否重要的​​是哪一个留下了:最低指数的那个,或者找到的最后一个。如果这很重要,您将需要重新排序我的字典示例以反向运行。我从最后开始,因为这样就可以在不使循环计数无效的情况下进行拼接(即通过在循环期间更改array.length)如果顺序很重要,则按常规正向循环并复制出每个字符串的第一次出现到一个新的数组,或修改这样的循环计数器。这可能是我使用的技术,因为它保留了顺序并保留了每个字符串的第一个遇到的实例:

import flash.utils.Dictionary;

var array:Array = ["harry","potter","ron","harry","snape","ginny","ron"];
var dict:Dictionary = new Dictionary();

var len:int = array.length;
for (var i:int = 0; i<len; ++i)
{
    var str:String = array[i] as String;
    if (!dict[str])
    {
        dict[str] = true;
    }
    else
    {
        array.splice(i,1);
        i--; len--;
    }
}

dict = null;


trace(array);

答案 1 :(得分:5)

更多猫皮肤:

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++;
}

答案 2 :(得分:4)

很好的答案!

我检查了一些,与我相比,效果更差。 这很简单:

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

使用我的数据进行统计:

Dict方法:8946ms,8718ms,8936ms

Obj方法:8800ms,8809ms,8769ms

我的老方法:8723毫秒,8599毫秒,8700毫秒

此方法:6771毫秒,6867毫秒,6706毫秒

答案 3 :(得分:3)

这是一种方法,我相信还有其他方法。

function removeDuplicate(sourceArray:Array) : void
{
    for (var i:int = 0; i < sourceArray.length - 1; i++)
    {
        for (var j:int = i + 1; j < sourceArray.length; j++)
        {
                if (sourceArray[i] === sourceArray[j])
                {   
                     // Remove duplicated element and decrease j index.
                     sourceArray.splice(j--, 1);
                }
        }
    }
}

答案 4 :(得分:1)

这是另一种方法,可能会更好看一下:

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);

这可能不是最有效的方法,@ prototypical的方法可能效率更高,但这是你要求的理论:)

答案 5 :(得分:1)

我投票支持亚当的选择,但后来我发现了这一点,在我看来,这可能会更好地表现呢?

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

这里的想法是你向后循环遍历数组,并且由于indexOf为你提供了第一个出现的索引,你可以用当前索引(i)检查找到的索引,如果不相同则删除。

答案 6 :(得分:1)

这是删除重复项的更优雅的方法:

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);
});

对数组的相同方法:

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);
    });

答案 7 :(得分:0)

如果sourceArray [i]不止一次匹配sourceArray [j],那么@prototypical的响应会不会出现问题,因为如果一个元素是.splice()d,那么sourceArray的长度会更短吗?

我已经重写了这个方法,以便从最后开始计算,这样就不会发生这种情况

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);
    }
}

答案 8 :(得分:0)

function removeDuplicateElement(_arr:Array):Array{
   //set new Dictionary
   var lDic:Dictionary = new Dictionary();
   for each(var thisElement:* in _arr){
      //All values of duplicate entries will be overwritten
      lDic[thisElement] = true;
   }
   _arr = [];
   for(var lKey:* in lDic){
     _arr.push(lKey);
  }
  return _arr;
}