2011-05-13 13 views

Respuesta

5

Más gato desollado:

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

De muchas maneras. Puede ordenar la matriz e iterar sobre ella ignorando las entradas que coincidan con la iteración anterior. O puede usar indexOf() para buscar duplicados. O puede tomar una pasada sobre la matriz, crear un diccionario con las cadenas (e ignorar las claves que ya tienen una entrada).

Aquí está la forma del diccionario, el costo de memoria de 1 booleano por entrada única, fácil en la memoria para cuando esperas un montón de engaños, y rápido. Si tiene relativamente pocos incautos, el tipo de sacrificio + duplicados consecutivos es probablemente más eficiente

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

Esta es una forma de clasificación, pero nota: ESTO NO preservar el orden! No dijiste si eso importa. Pero debido a que está utilizando una conexión rápida, tiende a tener un rendimiento O (N log N) más un pase adicional, a menos que, por supuesto, sus datos sean un caso patológico.

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

Además de no especificar si el orden importa, usted no dijo si importa cuál de los incautos que queda: el que está en el índice más bajo, o el último encontrado. Si eso es importante, deberá volver a ordenar mi ejemplo de diccionario para que se ejecute en la dirección opuesta. Empecé al final porque eso hace que sea correcto hacer un empalme sin invalidar el recuento de bucles (es decir, cambiando el array.length durante el bucle) Si el orden importa, gire en la dirección normal hacia adelante y copie la primera aparición de cada cadena a una nueva matriz, o modificar el contador de bucle de esta manera. Esta es probablemente la técnica que haría uso, ya que conserva el orden y mantiene el primer encontrado instancia de cada cadena:

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

Ésta es una manera de hacerlo, estoy seguro de que hay otros.

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

Eso lo haría en su lugar, pero es un desperdicio en términos de complejidad de tiempo, no la mejor solución. Hay muchas maneras de hacerlo que no son O (N^2). Exactamente qué solución es óptima para los datos reales depende un poco de lo que se espera de la frecuencia de los engañados. –

+0

sí, de acuerdo. Solo dándole un concepto con el que trabajar. En cualquier situación, puede elegir un martillo diferente. – prototypical

+0

Pero, supongo que un tutorial sobre todos los posibles martillos y sus pros y contras, podría valer la pena. Aunque voy a pasar eso por el momento. – prototypical

1

Ésta es otra manera de hacerlo, posiblemente un poco más agradable para mirar:

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

Esto probablemente no es la forma mas potente de hacerlo, @ método del prototipo es, probablemente, mucho más eficiente , pero es la teoría de que usted pidió :)

0

¿La respuesta de @prototypical no da problemas si el archivo sourceArray [i] coincide con el origen de la matriz [j] más de una vez porque la longitud de sourceArray sería más corta si un elemento ha sido .splice() d fuera de ella?

He reescrito este método a contar desde el final para que esto no suceda

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

He votado por la opción de Adán, pero luego me encontré con esto, y me parece que esto podría ser mejor rendimiento sabio todavía?

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

La idea aquí es que se recorre hacia atrás a través de la matriz, y desde indexOf le da el primer índice que ocurre, se puede comprobar el índice encontrado con el índice actual (i) y retirar si no es la misma.

3

¡Buenas respuestas!

He comprobado algunos de ellos, y tengo peores resultados en contraste con mi. Es muy sencillo:

var originalV : Vector.<String> = Vector.<String>(["a", "c", "d", "c", "b", "a", "e", "b", "a"]); 
var resultV : Vector.<String> = new Vector.<String>(); 

var i : int, len : uint = linkedReferencesArr.length; 
while(i < len) { 
    var el : String = linkedReferencesArr[i]; 
    if(resultV.indexOf(el) == -1) resultV.push(el); 
    i++; 
} 

trace(resultV); // here is vector with unique elements 

chicos Bienvenido!


Estadística con mi datos:

enfoque Dict: 8946ms, 8718ms, 8936ms

enfoque Obj: 8800ms, 8809ms, 8769ms

Mi viejo enfoque: 8723ms, 8599ms, 8700ms

Este enfoque: 6771ms, 6867ms, 6706ms

Cuestiones relacionadas