Conjuntos indexados

Flash Player 9 y posterior, Adobe AIR 1.0 y posterior

Los conjuntos indexados almacenan una serie de uno o varios valores organizados de forma que se pueda acceder a cada valor mediante un valor entero sin signo. El primer número de índice siempre es 0 y aumenta una unidad por cada elemento que se añada al conjunto. En ActionScript 3.0, se utilizan dos clases como conjuntos indexados: la clase Array y la clase Vector.

Los conjuntos indexados usan un entero de 32 bits sin signo como número de índice. El tamaño máximo de un conjunto indexado es 2 32 - 1 o 4.294.967.295. Si se intenta crear un conjunto de tamaño superior al tamaño máximo, se producirá un error en tiempo de ejecución.

Para acceder a un elemento individual de un conjunto indexado, debe utilizarse el operador de acceso a conjunto ( [] ) para especificar la posición del índice del elemento al que se desee acceder. Por ejemplo, el siguiente código representa el primer elemento (elemento en el índice 0) de un conjunto indexado llamado songTitles :

songTitles[0]

La combinación del nombre de la variable de conjunto seguido del índice entre corchetes hace las veces de identificador único. (Dicho de otro modo, se puede utilizar en cualquier situación en la que se utilizaría un nombre de variable). Es posible asignar un valor a un elemento de conjunto indexado utilizando el nombre y el índice situados a la izquierda de la sentencia de asignación:

songTitles[1] = "Symphony No. 5 in D minor";

Del mismo modo, se puede recuperar el valor de un elemento de conjunto indexado utilizando el nombre y el índice situados a la derecha de una sentencia de asignación:

var nextSong:String = songTitles[2];

También se puede utilizar una variable entre corchetes, en vez de proporcionar un valor explícito. (La variable debe contener un valor entero no negativo, como un uint, un int positivo o una instancia positiva entera de Number). Esta técnica suele utilizarse para “recorrer en bucle” los elementos de un conjunto indexado y llevar a cabo una operación en uno o en todos los elementos. El siguiente código muestra esta técnica. El código utiliza un bucle para acceder a cada valor de un objeto Array llamado oddNumbers . Utiliza la sentencia trace() para imprimir cada valor con la forma “oddNumber[ índice ] = valor ”:

var oddNumbers:Array = [1, 3, 5, 7, 9, 11]; 
var len:uint = oddNumbers.length; 
for (var i:uint = 0; i < len; i++) 
{ 
    trace("oddNumbers[" + i.toString() + "] = " + oddNumbers[i].toString()); 
}

Clase Array

El primer tipo de conjunto indexado es la clase Array. Una instancia de Array puede contener un valor de cualquier tipo de datos. El mismo objeto Array puede contener objetos que sean de distinto tipo de datos. Por ejemplo, una sola instancia de Array puede tener un valor de String en el índice 0, una instancia de Number en el índice 1 y un objeto XML en el índice 2.

Clase Vector

Otro tipo de conjunto indexado disponible en ActionScript 3.0 es la clase Vector. Una instancia de Vector es un conjunto de tipos , lo que significa que todos los elementos de una instancia de Vector siempre son del mismo tipo.

Nota: la clase Vector está disponible a partir de Flash Player 10 y Adobe AIR 1.5.

Al declarar una variable Vector o crear una instancia de un objeto Vector, se especifica explícitamente el tipo de datos de los objetos que dicho vector puede contener. El tipo de datos especificado se conoce como tipo base del vector. En tiempo de ejecución y de compilación (en modo estricto), se comprueba cualquier código que establezca el valor de un elemento Vector o que recupere un valor desde un vector. Si el tipo de datos del objeto que se añade o se recupera no coincide con el tipo base del vector, se produce un error.

Además de la restricción del tipo de datos, la clase Vector tiene otras limitaciones que la distinguen de la clase Array:

  • Una vector es un conjunto denso. Un objeto Array puede tener valores en los índices 0 y 7, incluso si no tiene valores en las posiciones 1-6. Sin embargo, un vector debe tener un valor (o null ) en todos los índices.

  • Opcionalmente, un vector puede tener longitud fija. Esto significa que el número de elementos contenidos por el vector no puede cambiar.

  • El acceso a los elementos de un vector está definido por sus límites. Nunca se puede leer un valor de un índice superior a la ( longitud - 1) del elemento final. Nunca se puede establecer un valor con un índice superior al índice final actual. Dicho de otro modo, solo se puede establecer un valor en un índice existente o en una [longitud] de índice.

La consecuencia de estas restricciones hace que utilizar un vector presente tres ventajas principales frente a una instancia de Array cuyos elementos sean todos instancias de una sola clase:

  • Rendimiento: el acceso y la iteración en los elementos de un conjunto son mucho más rápidos si se utiliza una instancia de Vector y no una de Array.

  • Seguridad de tipos: en modo estricto, el compilador puede identificar errores de tipos de datos. Algunos ejemplos de este tipo de errores incluyen la asignación de un valor del tipo de datos incorrecto a un vector, o esperar un tipo de datos incorrecto al leer un valor en un vector. En tiempo de ejecución, los tipos de datos también se comprueban al añadir datos o leerlos en un objeto Vector. Tenga en cuenta, no obstante, que cuando se utiliza el método push() o el método unshift() para añadir valores a un vector, los tipos de datos de los argumentos no se comprueban en tiempo de compilación. Cuando se utilizan estos métodos, los valores se siguen comprobando en tiempo de ejecución.

  • Fiabilidad: la comprobación del rango del motor de ejecución (o la comprobación de la longitud fija) aumenta la fiabilidad sobre los conjuntos en gran medida.

Dejando a un lado las restricciones y ventajas adicionales, la clase Vector es muy similar a la clase Array. Las propiedades y los métodos de un objeto Vector son similares (la mayoría de las veces, idénticos) a las propiedades y métodos de un objeto Array. En la mayor parte de las situaciones en las que utilizaría un objeto Array con todos sus elementos del mismo tipo de datos, es preferible usar una instancia del objeto Vector.

Creación de conjuntos

Se pueden utilizar diversas técnicas para crear una instancia de Array o una instancia de Vector. No obstante, las técnicas para crear cada tipo de conjunto son ligeramente distintas.

Creación de una instancia de Array

Para crear un objeto Array, llame al constructor Array() o utilice la sintaxis literal de Array.

La función constructora de Array() se puede utilizar de tres maneras distintas. En primer lugar, si se llama al constructor sin argumentos, se obtiene un conjunto vacío. Se puede utilizar la propiedad length de la clase Array para comprobar que el conjunto no tiene elementos. Por ejemplo, el código siguiente llama al constructor de Array() sin argumentos:

var names:Array = new Array(); 
trace(names.length); // output: 0

En segundo lugar, si se utiliza un número como único parámetro del constructor de Array() , se crea un conjunto de esa longitud y se establece el valor de cada elemento en undefined . El argumento debe ser un entero sin signo entre 0 y 4.294.967.295. Por ejemplo, el código siguiente llama al constructor de Array() con un solo argumento numérico:

var names:Array = new Array(3); 
trace(names.length); // output: 3 
trace(names[0]); // output: undefined 
trace(names[1]); // output: undefined 
trace(names[2]); // output: undefined

En tercer lugar, si se llama al constructor y se le pasa una lista de elementos como parámetros, se crea un conjunto con elementos correspondientes a cada uno de los parámetros. El código siguiente pasa tres argumentos al constructor de Array() :

var names:Array = new Array("John", "Jane", "David"); 
trace(names.length); // output: 3 
trace(names[0]); // output: John 
trace(names[1]); // output: Jane 
trace(names[2]); // output: David

También es posible crear conjuntos con literales de conjunto. Un literal de conjunto se puede asignar directamente a una variable de tipo conjunto, como se indica en el siguiente ejemplo:

var names:Array = ["John", "Jane", "David"];

Creación de una instancia de Vector

Para crear una instancia de Vector, llame al constructor Vector.<T>() . También es posible crear un vector llamando a la función global Vector.<T>() . Esta función convierte el objeto especificado en una instancia de Vector. En Flash Professional CS5, Flash Builder 4 y Flex 4 y versiones posteriores de estas aplicaciones, también se puede crear una instancia del vector utilizando la sintaxis literal de Vector.

Cada vez que se declara una variable Vector (o, del mismo modo, un parámetro del método Vector o un tipo devuelto del método), se debe especificar el tipo base de la variable Vector. También se debe especificar el tipo base al crear una instancia de Vector llamando al constructor Vector.<T>() . Dicho de otro modo, cada vez que se utiliza el término Vector en ActionScript, va acompañado de un tipo base.

Puede especificar el tipo base de Vector mediante la sintaxis de parámetros de tipos. El parámetro type va inmediatamente después de la palabra Vector en el código. Está formado por un punto ( . ) seguido de la clase base encerrada entre paréntesis angulares ( <> ), tal como puede verse en este ejemplo:

var v:Vector.<String>; 
v = new Vector.<String>();

En la primera línea del ejemplo, la variable v se declara como una instancia de Vector.<String> . Es decir, representa un conjunto indexado que solo puede contener instancias de String. La segunda línea llama al constructor Vector() para crear una instancia del mismo tipo de vector (es decir, un vector cuyos elementos sean todos objetos String). Asigna el objeto a v .

Uso del constructor Vector.<T>()

Si utiliza el constructor Vector.<T>() sin ningún argumento, crea una instancia vacía de Vector. Puede comprobar si un vector está vacío observando su propiedad length . Por ejemplo, el siguiente código llama al constructor Vector.<T>() sin ningún argumento:

var names:Vector.<String> = new Vector.<String>(); 
trace(names.length); // output: 0

Si conoce con antelación el número de elementos que necesita el vector inicialmente, puede predefinir el número de elementos contenidos en Vector. Para crear un vector con un determinado número de elementos, transfiera el número de elementos como primer parámetro (el parámetro length ). Puesto que los elementos Vector no pueden estar vacíos, se llenan con instancias del tipo base. Si el tipo base es un tipo de referencia que admite valores null , todos los elementos contendrán null . En caso contrario, todos los elementos contienen el valor predeterminado para la clase. Por ejemplo, una variable uint no puede ser null . En consecuencia, en el siguiente código, el vector llamado ages se crea con siete elementos (cada uno con el valor 0):

var ages:Vector.<uint> = new Vector.<uint>(7); 
trace(ages); // output: 0,0,0,0,0,0,0 

Finalmente, con el constructor Vector.<T>() , también es posible crear un vector de longitud fija si se transfiere true como segundo parámetro (el parámetro fixed ). En ese caso, el vector se crea con el número especificado de elementos y este número no puede cambiar. Debe tenerse en cuenta, no obstante, que sigue siendo posible cambiar los valores de los elementos de un vector de longitud fija.

Uso del constructor de sintaxis literal de Vector

En Flash Professional CS5, Flash Builder 4, Flex 4 y versiones posteriores de estas aplicaciones, se puede transmitir una lista de valores al constructor Vector.<T>() para especificar los valores iniciales de Vector:

// var v:Vector.<T> = new <T>[E0, ..., En-1 ,]; 
// For example: 
var v:Vector.<int> = new <int>[0,1,2,];

La siguiente información se aplica a esta sintaxis:

  • La coma final es opcional.

  • Los elementos vacíos del conjunto no se admiten; una sentencia como, por ejemplo, var v:Vector.<int> = new <int>[0,,2,] genera un error del compilador.

  • No se puede especificar una longitud predeterminada para la instancia de Vector. En cambio, la longitud es la misma que el número de elementos en la lista de inicialización.

  • No es posible especificar si la instancia de Vector presenta una longitud fija. En su lugar, utilice la propiedad fixed .

  • Los errores o la pérdida de datos se pueden producir si los elementos transmitidos como valores no coinciden con el tipo especificado. Por ejemplo:
    var v:Vector.<int> = new <int>[4.2]; // compiler error when running in strict mode 
    trace(v[0]); //returns 4 when not running in strict mode

Uso del constructor Vector.<T>()

Además del constructor Vector.<T>() y los constructores de sintaxis literal de Vector, también se puede utilizar la función global Vector.<T>() para crear un objeto Vector. La función global Vector.<T>() es una función de conversión. Al llamar a la función global Vector.<T>() , se especifica el tipo base del vector devuelto por el método. Se transfiere un conjunto indexado sencillo (instancia de Array o de Vector) como argumento. El método devuelve un vector con el tipo base especificado y con los valores del argumento del conjunto original. El siguiente código muestra la sintaxis para llamar a la función global Vector.<T>() :

var friends:Vector.<String> = Vector.<String>(["Bob", "Larry", "Sarah"]);

La función global Vector.<T>() lleva a cabo la conversión de tipos de datos en dos niveles. En primer lugar, cuando se transfiere una instancia de Array a la función, se devuelve una instancia de Vector. En segundo lugar, sea o no el conjunto original una instancia de Array o de Vector, la función intenta convertir los elementos del conjunto original en valores del tipo base. La conversión utilizar reglas de conversión estándar de tipos de datos de ActionScript. Por ejemplo, el siguiente código convierte los valores de String del objeto Array original en enteros del vector resultante. La parte decimal del primer valor ( "1.5" ) se corta y el tercer valor no numérico ( "Waffles" ) se convierte a 0 en el resultado:

var numbers:Vector.<int> = Vector.<int>(["1.5", "17", "Waffles"]); 
trace(numbers); // output: 1,17,0

Si no es posible convertir alguno de los elementos originales, se produce un error.

Cuando el código llama a la función global Vector.<T>() , si un elemento del conjunto original es una instancia de una subclase del tipo base especificado, el elemento se añade al vector resultante (y no se produce ningún error). Utilizar la función global Vector.<T>() es el único modo de convertir un vector con tipo base T en uno con un tipo base que sea una superclase de T .

Inserción de elementos de conjunto

La forma más sencilla de añadir un elemento a un conjunto indexado es utilizar el operador de acceso a conjunto ( [] ). Para establecer el valor de un elemento de conjunto indexado, utilice el nombre del objeto Array o Vector y el número de índice situado a la izquierda de una sentencia de asignación:

songTitles[5] = "Happy Birthday";

Si el objeto Array o Vector no tiene aún ningún elemento en ese índice, este se crea y se almacena el valor en él. Si ya existe un valor en el índice, el nuevo valor sustituye al existente.

Un objeto Array permite crear un elemento en cualquier índice. Sin embargo, con un objeto Vector solo es posible asignar un valor a un índice existente o al siguiente índice disponible. El siguiente índice disponible corresponde a la propiedad length del objeto Vector. El modo más seguro de añadir un nuevo elemento a un objeto Vector es utilizar un código como el siguiente:

myVector[myVector.length] = valueToAdd;

Tres de los métodos de la clase Array y Vector ( push() , unshift() y splice() ) permiten insertar elementos en un conjunto indexado. El método push() añade uno o varios elementos al final de un conjunto. Es decir, el último elemento insertado en el conjunto mediante el método push() tendrá el número de índice más alto. El método unshift() inserta uno o más elementos al principio de un conjunto, que siempre tiene el número de índice 0. El método splice() insertará un número arbitrario de elementos en un índice especificado del conjunto.

En el ejemplo siguiente se ilustran los tres métodos. Un conjunto denominado planets se crea para almacenar los nombres de los planetas en orden de proximidad al sol. En primer lugar, se llama al método push() para agregar el elemento inicial, Mars . En segundo lugar, se llama al método unshift() para insertar el elemento que debe estar al principio del conjunto, Mercury . Por último, se llama al método splice() para insertar los elementos Venus y Earth a continuación de Mercury , pero antes de Mars . El primer argumento enviado a splice() , el entero 1, dirige la inserción para que se realice en el número de índice 1. El segundo argumento enviado a splice() , el entero 0, indica que no se debe eliminar ningún elemento. Por último, el tercer y el cuarto argumento enviados a splice() , Venus y Earth son los elementos que se van a insertar.

var planets:Array = new Array(); 
planets.push("Mars"); // array contents: Mars 
planets.unshift("Mercury"); // array contents: Mercury,Mars 
planets.splice(1, 0, "Venus", "Earth"); 
trace(planets); // array contents: Mercury,Venus,Earth,Mars

Los métodos push() y unshift() devuelven un entero sin signo que representa la longitud del conjunto modificado. El método splice() devuelve un conjunto vacío cuando se utiliza para insertar elementos, algo que puede parecer extraño, pero que tiene sentido si se tiene en cuenta la versatilidad que ofrece splice() . Se puede utilizar el método splice() no solo para insertar elementos en un conjunto, sino también para eliminar elementos de un conjunto. Cuando se utiliza para eliminar elementos, el método splice() devuelve un conjunto que contiene los elementos eliminados.

Nota: si la propiedad fixed de un objeto Vector es true , el número total de elementos de dicho vector es invariable. Si intenta añadir un nuevo elemento a un vector de longitud fija con las técnicas descritas anteriormente, se producirá un error.

Recuperación de valores y eliminación de elementos de conjunto

El modo más sencillo de recuperar el valor de un elemento en un conjunto indexado es utilizar el operador de acceso a conjunto ( [] ). Para recuperar el valor de un elemento de conjunto indexado, utilice el nombre del objeto Array o Vector y el número de índice situado a la derecha de una sentencia de asignación:

var myFavoriteSong:String = songTitles[3];

Se puede intentar recuperar un valor de un objeto Array o Vector utilizando un índice en el que no exista ningún elemento. En ese caso, un objeto Array devuelve el valor undefined y un objeto Vector emite una excepción RangeError.

Tres métodos de las clases Array y Vector ( pop() , shift() y splice() ) permiten eliminar elementos. El método pop() elimina un elemento del final del conjunto. Es decir, elimina el elemento que tenga el número de índice más alto. El método shift() elimina un elemento del principio del conjunto, lo que significa que siempre elimina el elemento con el número de índice 0. El método splice() , que también se puede utilizar para insertar elementos, elimina un número arbitrario de elementos empezando por el que tiene el número de índice especificado por el primer argumento enviado al método.

En el ejemplo siguiente se utilizan los tres métodos para eliminar elementos de una instancia de Array. Se crea un conjunto denominado oceans para almacenar los nombres de grandes masas de agua. Algunos de los nombres del conjunto son lagos, no océanos, por lo que hay que eliminarlos.

En primer lugar, se utiliza el método splice() para eliminar los elementos Aral y Superior , e insertar los elementos Atlantic e Indian . El primer argumento enviado a splice() , el entero 2, indica que la operación debe empezar por el tercer elemento de la lista, que tiene el índice 2. El segundo argumento, 2, indica que hay que eliminar dos elementos. Los restantes argumentos, Atlantic e Indian , son valores que deben insertarse a partir del índice 2.

En segundo lugar, se utiliza el método pop() para eliminar el último elemento del conjunto, Huron . Y por último, se utiliza el método shift() para eliminar el primer elemento del conjunto, Victoria .

var oceans:Array = ["Victoria", "Pacific", "Aral", "Superior", "Indian", "Huron"]; 
oceans.splice(2, 2, "Arctic", "Atlantic"); // replaces Aral and Superior 
oceans.pop(); // removes Huron 
oceans.shift(); // removes Victoria 
trace(oceans);// output: Pacific,Arctic,Atlantic,Indian

Los métodos pop() y shift() devuelven el elemento eliminado. En una instancia de Array, el tipo de datos del valor devuelto es Object, ya que los conjuntos pueden contener valores de cualquier tipo de datos. En una instancia de Vector, el tipo de datos del valor es el tipo base del vector. El método splice() devuelve un objeto Array o Vector que contiene los valores eliminados. Se puede modificar el ejemplo del conjunto oceans de forma que la llamada a splice() asigne el conjunto devuelto a una nueva variable de Array, como se indica en el siguiente ejemplo:

var lakes:Array = oceans.splice(2, 2, "Arctic", "Atlantic"); 
trace(lakes); // output: Aral,Superior

Es posible encontrar código que utilice el operador delete en un elemento del objeto Array. El operador delete establece el valor de un elemento de conjunto en undefined , pero no elimina el elemento del objeto Array. Por ejemplo, el código siguiente utiliza el operador delete en el tercer elemento del conjunto oceans , pero la longitud del conjunto sigue siendo 5:

var oceans:Array = ["Arctic", "Pacific", "Victoria", "Indian", "Atlantic"]; 
delete oceans[2]; 
trace(oceans);// output: Arctic,Pacific,,Indian,Atlantic 
trace(oceans[2]); // output: undefined 
trace(oceans.length); // output: 5

Se puede utilizar la propiedad length de un conjunto para truncar un objeto Array o Vector. Si se establece la propiedad length de un conjunto indexado como una longitud inferior a la longitud actual del conjunto, este se trunca y se eliminan todos los valores almacenados en los números de índice superiores al nuevo valor de length menos 1. Por ejemplo, si el conjunto oceans se ordena de modo que todas las entradas válidas están al principio del conjunto, se puede utilizar la propiedad length para eliminar las entradas situadas al final, tal como se indica en el siguiente código:

var oceans:Array = ["Arctic", "Pacific", "Victoria", "Aral", "Superior"]; 
oceans.length = 2; 
trace(oceans); // output: Arctic,Pacific
Nota: si la propiedad fixed de un objeto Vector es true , el número total de elementos de dicho vector es invariable. Si intenta eliminar o truncar un elemento de un vector de longitud fija utilizando las técnicas descritas anteriormente, se producirá un error.

Ordenación de un conjunto

Hay tres métodos, reverse() , sort() y sortOn() , que permiten cambiar el orden de un conjunto indexado, ordenando o invirtiendo el orden. Todos estos métodos modifican el conjunto existente. En la tabla siguiente se resumen estos métodos y su comportamiento en los objetos Array y Vector:

Método

Comportamiento de Array

Comportamiento de Vector

reverse()

Cambia el orden del conjunto de forma que el último elemento se convierte en el primero, el penúltimo elemento se convierte en el segundo, etc.

Idéntico al comportamiento de Array.

sort()

Permite ordenar los elementos del conjunto de diversas formas predefinidas, por ejemplo, por orden alfabético o numérico. También es posible especificar un algoritmo de ordenación personalizado.

Ordena los elementos según el algoritmo de ordenación personalizado especificado.

sortOn()

Permite ordenar objetos con una o varias propiedades comunes y utilizar las propiedades como claves de ordenación.

No disponible en la clase Vector.

Método reverse()

El método reverse() no admite parámetros y no devuelve un valor, pero permite alternar el orden del conjunto de su estado actual al orden inverso. El ejemplo siguiente invierte el orden de los océanos que se muestra en el conjunto oceans :

var oceans:Array = ["Arctic", "Atlantic", "Indian", "Pacific"]; 
oceans.reverse(); 
trace(oceans); // output: Pacific,Indian,Atlantic,Arctic

Ordenación básica con el método sort() (solo en la clase Array)

En una instancia de Array, el método sort() reorganiza los elementos de un conjunto con el orden de clasificación predeterminado . El orden de clasificación predeterminado tiene las siguientes características:

  • En la ordenación se distinguen mayúsculas de minúsculas, lo que significa que los caracteres en mayúsculas preceden a los caracteres en minúsculas. Por ejemplo, la letra D precede a la letra b.

  • La ordenación es ascendente, lo que significa que los códigos de caracteres inferiores (como A) preceden a los códigos de caracteres superiores (como B).

  • La ordenación coloca juntos los valores idénticos, pero no usa un orden específico.

  • La ordenación se basa en cadenas, lo que significa que los elementos se convierten en cadenas antes de ser comparados (por ejemplo, 10 precede a 3 porque el código de carácter de la cadena "1" es inferior al de la cadena "3" ).

A veces hay que ordenar el conjunto sin tener en cuenta mayúsculas o minúsculas, o en orden descendente, o si el conjunto contiene números hay que ordenar numéricamente en lugar de alfabéticamente. El método sort() de la clase Array tiene un parámetro options que permite modificar todas las características del orden de clasificación predeterminado. Las opciones se definen mediante un conjunto de constantes estáticas de la clase Array, como se indica en la lista siguiente:

  • Array.CASEINSENSITIVE : esta opción hace que no se tengan en cuenta las diferencias de mayúsculas y minúsculas en la ordenación. Por ejemplo, la b minúscula precede a la D mayúscula.

  • Array.DESCENDING: invierte la ordenación ascendente predeterminada. Por ejemplo, la letra B precede a la letra A.

  • Array.UNIQUESORT: hace que se cancele la ordenación si se encuentran dos valores idénticos.

  • Array.NUMERIC: hace que la ordenación sea numérica, de forma que 3 preceda a 10.

En el ejemplo siguiente se ilustran algunas de estas opciones. Se crea un conjunto denominado poets que se ordena con varias opciones distintas.

var poets:Array = ["Blake", "cummings", "Angelou", "Dante"]; 
poets.sort(); // default sort 
trace(poets); // output: Angelou,Blake,Dante,cummings 
 
poets.sort(Array.CASEINSENSITIVE); 
trace(poets); // output: Angelou,Blake,cummings,Dante 
 
poets.sort(Array.DESCENDING); 
trace(poets); // output: cummings,Dante,Blake,Angelou 
 
poets.sort(Array.DESCENDING | Array.CASEINSENSITIVE); // use two options 
trace(poets); // output: Dante,cummings,Blake,Angelou

Ordenación personalizada con el método sort() (clases Array y Vector)

Además de la ordenación básica disponible en los objetos Array, también es posible definir una regla de ordenación personalizada. Esta técnica es la única forma del método sort() disponible para la clase Vector. Para definir una ordenación personalizada, debe escribir una función de ordenación personalizada y transferirla como argumento al método sort() .

Por ejemplo, si se tiene una lista de nombres en la que cada elemento de la lista contiene el nombre completo de una persona, pero se desea ordenar la lista por apellido, hay que utilizar una función de ordenación personalizada que analice cada elemento y use el apellido en la función de ordenación. El código siguiente muestra cómo se puede hacer esto con una función personalizada que se utiliza como parámetro del método Array.sort() :

var names:Array = new Array("John Q. Smith", "Jane Doe", "Mike Jones"); 
function orderLastName(a, b):int 
{ 
    var lastName:RegExp = /\b\S+$/; 
    var name1 = a.match(lastName); 
    var name2 = b.match(lastName); 
    if (name1 < name2) 
    { 
        return -1; 
    } 
    else if (name1 > name2) 
    { 
        return 1; 
    } 
    else 
    { 
        return 0; 
    } 
} 
trace(names); // output: John Q. Smith,Jane Doe,Mike Jones 
names.sort(orderLastName); 
trace(names); // output: Jane Doe,Mike Jones,John Q. Smith

La función de ordenación personalizada orderLastName() utiliza una expresión regular para extraer el apellido de cada elemento que se va a utilizar para la operación de comparación. Se utiliza el identificador de la función orderLastName como único parámetro al llamar al método sort() del conjunto names . La función de ordenación acepta dos parámetros, a y b , ya que procesa dos elementos de conjunto cada vez. El valor devuelto por la función de ordenación indica cómo deben ordenarse los elementos:

  • Si el valor devuelto es -1, indica que el primer parámetro, a , precede al segundo parámetro, b .

  • Si el valor devuelto es 1, indica que el segundo parámetro, b , precede al primero, a .

  • Si el valor devuelto es 0, indica que los elementos tienen igual precedencia de ordenación.

Método sortOn() (solo en la clase Array)

El método sortOn() está diseñado para objetos Array con elementos que contienen objetos. Se espera que estos objetos tengan al menos una propiedad en común que se pueda utilizar como criterio de ordenación. El uso del método sortOn() en conjuntos de cualquier otro tipo puede producir resultados inesperados.

Nota: la clase Vector no incluye un método sortOn() . Este método solo está disponible en objetos Array.

El ejemplo siguiente revisa el conjunto poets de forma que cada elemento sea un objeto en lugar de una cadena. Cada objeto contiene el apellido del poeta y el año de nacimiento.

var poets:Array = new Array(); 
poets.push({name:"Angelou", born:"1928"}); 
poets.push({name:"Blake", born:"1757"}); 
poets.push({name:"cummings", born:"1894"}); 
poets.push({name:"Dante", born:"1265"}); 
poets.push({name:"Wang", born:"701"});

Se puede utilizar el método sortOn() para ordenar el conjunto por la propiedad born . El método sortOn() define dos parámetros, fieldName y options . El argumento fieldName debe especificarse como una cadena. En el ejemplo siguiente, se llama a sortOn() con dos argumentos, "born" y Array.NUMERIC . Se utiliza el argumento Array.NUMERIC para asegurarse de que la ordenación se realiza numéricamente en lugar de alfabéticamente. Esto es una práctica recomendable, incluso en el caso de que todos los números tengan el mismo número de dígitos, ya que garantiza que la ordenación seguirá comportándose de la manera esperada si posteriormente se añade un número con menos (o más) dígitos al conjunto.

poets.sortOn("born", Array.NUMERIC); 
for (var i:int = 0; i < poets.length; ++i) 
{ 
    trace(poets[i].name, poets[i].born); 
} 
/* output: 
Wang 701 
Dante 1265 
Blake 1757 
cummings 1894 
Angelou 1928 
*/

Ordenación sin modificar el conjunto original (solo en la clase Array)

Generalmente, los métodos sort() y sortOn() modifican un conjunto. Si se desea ordenar un conjunto sin modificarlo, se debe pasar la constante Array.RETURNINDEXEDARRAY como parte del parámetro options . Esta opción ordena a los métodos que devuelvan un nuevo conjunto que refleje la ordenación y deje el conjunto original sin cambios. El conjunto devuelto por los métodos es un conjunto simple de números de índice que refleja el nuevo orden de clasificación y no contiene ningún elemento del conjunto original. Por ejemplo, para ordenar el conjunto poets por año de nacimiento sin modificar el conjunto, se debe incluir la constante Array.RETURNINDEXEDARRAY como parte del argumento pasado para el parámetro options .

El ejemplo siguiente almacena la información de índice devuelta en un conjunto denominado indices y utiliza el conjunto indices junto con el conjunto poets sin modificar para mostrar los poetas ordenados por año de nacimiento:

var indices:Array; 
indices = poets.sortOn("born", Array.NUMERIC | Array.RETURNINDEXEDARRAY); 
for (var i:int = 0; i < indices.length; ++i) 
{ 
    var index:int = indices[i]; 
    trace(poets[index].name, poets[index].born); 
} 
/* output: 
Wang 701 
Dante 1265 
Blake 1757 
cummings 1894 
Angelou 1928 
*/

Realización de consultas en un conjunto

Cuatro métodos de las clases Array y Vector ( concat() , join() , slice() y toString() ) consultan el conjunto para obtener información, pero no lo modifican. Los métodos concat() y slice() devuelven conjuntos nuevos, mientras que los métodos join() y toString() devuelven cadenas. El método concat() requiere una nuevo conjunto o lista de elementos como argumentos, y los combina con el conjunto existente para crear una nuevo conjunto. El método slice() tiene dos parámetros, denominados startIndex y endIndex , y devuelve un nuevo conjunto que contiene una copia de los elementos "extraídos" del conjunto existente. Se empieza por extraer el elemento con índice startIndex y el último elemento extraído es el que tiene el índice inmediatamente anterior a endIndex . Esto conlleva una repetición: el elemento con índice endIndex no se incluye en el valor devuelto.

En el ejemplo siguiente se utilizan concat() y slice() para crear conjuntos nuevos a partir de elementos de otros conjuntos:

var array1:Array = ["alpha", "beta"]; 
var array2:Array = array1.concat("gamma", "delta"); 
trace(array2); // output: alpha,beta,gamma,delta 
 
var array3:Array = array1.concat(array2); 
trace(array3); // output: alpha,beta,alpha,beta,gamma,delta 
 
var array4:Array = array3.slice(2,5); 
trace(array4); // output: alpha,beta,gamma

Se pueden utilizar los métodos join() y toString() para consultar el conjunto y devolver su contenido en forma de cadena. Si no se utiliza ningún parámetro para el método join() , los dos métodos se comportarán de forma idéntica: devolverán una cadena que contiene una lista delimitada por comas de todos los elementos del conjunto. El método join() , a diferencia del método toString() , admite un parámetro denominado delimiter , que permite elegir el símbolo que se debe utilizar como separador entre cada elemento de la cadena devuelta.

En el ejemplo siguiente se crea un conjunto denominado rivers y se llama a join() y toString() para devolver los valores del conjunto en forma de cadena. El método toString() se utiliza para devolver valores separados por comas ( riverCSV ), mientras que el método join() se utiliza para devolver valores separados por el carácter + .

var rivers:Array = ["Nile", "Amazon", "Yangtze", "Mississippi"]; 
var riverCSV:String = rivers.toString(); 
trace(riverCSV); // output: Nile,Amazon,Yangtze,Mississippi 
var riverPSV:String = rivers.join("+"); 
trace(riverPSV); // output: Nile+Amazon+Yangtze+Mississippi

Una característica del método join() que hay tener en cuenta es que las instancias anidadas de Array o Vector siempre se devuelven con los valores separados por comas, independientemente del separador que se especifique para los elementos del conjunto principal, como se indica en el siguiente ejemplo:

var nested:Array = ["b","c","d"]; 
var letters:Array = ["a",nested,"e"];  
var joined:String = letters.join("+"); 
trace(joined); // output: a+b,c,d+e