配列のソート

インデックス配列要素の並び順を変更する場合は、ソートまたは順序の逆転を行う reverse()sort()sortOn() の 3 つのメソッドを使用できます。いずれのメソッドでも既存の配列が変化します。 次の表に、Array オブジェクトおよび Vector オブジェクトのこれらのメソッドとその動作をまとめます。

メソッド

配列の動作

ベクターの動作

reverse()

要素の並び順を逆転します。つまり、末尾にあった要素は先頭に、末尾の直前にあった要素は 2 番目に移動します。

配列の動作と同じです。

sort()

アルファベット順、番号順など、事前に定義した様々な方法で配列の要素をソートすることができます。また、カスタムのソートアルゴリズムを指定することもできます。

指定するカスタムのソートアルゴリズムに従って要素をソートします。

sortOn()

ソート キーとして使用する 1 つ以上のプロパティを指定して、1 つ以上の共通プロパティを含むオブジェクトをソートすることができます。

Vector クラスでは使用できません。

reverse() メソッド

reverse() メソッドは、パラメータも戻り値もありませんが、既存の配列について現在の状態と、その並び順を逆転した状態とを切り替えるのに使用できます。次の例では、oceans 配列に格納した海の名前を元とは逆の順序に並べ替えます。

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

sort() メソッドを使用した基本的なソート(Array クラスのみ)

Array インスタンスでは、sort() メソッドがデフォルトのソート順を使用して配列要素を並べ替えます。このデフォルトのソート順には、次の特性があります。

  • 大文字と小文字は区別され、大文字の方が小文字より先に並びます。 例えば、D は b よりも先に並びます。

  • ソート方向は正順です。つまり、文字コードの値の小さい文字 (例 : A) の方が、文字コードの値の大きい文字 (例 : B) よりも先に並びます。

  • 値が同等と見なされる要素は互いに隣接して並びますが、それらの間における並び順は決まっていません。

  • ソートはストリングベースで実行されます。つまり、要素は文字列に変換してから比較されます。例えば、数値の 10 は 3 よりも先に並びます。これは、ストリング「1」の文字コードの方がストリング「3」の文字コードよりも小さいためです。

大文字と小文字を区別しないソート、逆順のソート、またはアルファベット順でなく数値の大きさ順によるソートなどが必要な場合のために、Array クラスの sort() メソッドには、デフォルトのソート順に定められた各種の規則を変更する options パラメータがあります。こうしたオプションは、次に示す Array クラスの静的定数セットによって定義されます。

  • Array.CASEINSENSITIVE:このオプションにより、ソートで大文字と小文字が無視されます。これにより、例えば小文字の b が大文字の D よりも先に並ぶようになります。

  • Array.DESCENDING:デフォルトの正順ではなく逆順でソートします。例えば、B が A よりも先に並ぶようになります。

  • Array.UNIQUESORT:同じ値を持つ複数の要素が見つかった場合にソートを中止するようにします。

  • Array.NUMERIC:数値順でソートします。例えば、3 が 10 よりも先に並ぶようになります。

これらのオプションの一部を使用した例を次に示します。 poets という名前の配列を作成し、いろいろなオプションを使用してソートを実行しています。

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

sort() メソッドを使用したカスタムソート(Array クラスおよび Vector クラス)

Array オブジェクトで使用可能な基本のソートの他に、カスタムのソート規則を定義することもできます。このテクニックは、Vector クラスで使用可能な唯一の形式の sort() メソッドです。カスタムソートを定義するには、カスタムのソート関数を作成し、それを sort() メソッドに引数として渡します。

例えば、各人のフルネームを要素として格納した人名リストがあるとします。このリストを姓を基準にして並べ替える場合は、各要素を解析して姓の部分を比較するソート関数を独自に作成する必要があります。これを実現するコード例を、次に示します。この例では、カスタム関数を 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

独自のソート関数 orderLastName() では、正規表現を使用して各要素から姓の部分を抽出し、それを比較演算に使用します。names 配列に対する sort() メソッド呼び出しのパラメータとして、この関数の識別子である orderLastName だけを指定しています。ソート関数に a および b の 2 つのパラメータが渡されるのは、一度に 2 つの配列要素が処理の対象となるからです。ソート関数の戻り値は 2 つの要素の並び順を示すものであり、次の意味があります。

  • 戻り値が -1 の場合、第 1 パラメータの a を第 2 パラメータの b よりも先に並べることを示します。

  • 戻り値が 1 の場合、第 2 パラメータの b を第 1 パラメータの a よりも先に並べることを示します。

  • 戻り値が 0 の場合、2 つの要素がソートにおいて同じ順位を持つことを示します。

sortOn() メソッド(Array クラスのみ)

sortOn() メソッドは、要素がオブジェクトである Array オブジェクト用に作成されました。すべての要素のオブジェクトには、ソート用キーとなる共通のプロパティが少なくとも 1 つ含まれている必要があります。 これらの条件に合わない配列に対して sortOn() メソッドを使用した場合の結果は予測不能です。

注意: Vector クラスには、sortOn() メソッドはありません。このメソッドは、Array オブジェクトでのみ有効です。

次の例は、poets 配列をストリング要素ではなくオブジェクト要素の配列に改変したものです。各オブジェクトには、詩人の姓と生誕年が格納されています。

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

この配列では、born プロパティを基準として sortOn() メソッドによるソートを実行できます。sortOn() メソッドには、fieldName および options の 2 つのパラメータがあります。fieldName にはストリングを指定する必要があります。次の例では、sortOn() にパラメータとして「born」および Array.NUMERIC の 2 つを渡しています。Array.NUMERIC オプションを指定しているのは、アルファベット順ではなく数値順で確実にソートを実行するためです。たとえ各要素に格納されている数値の桁数がすべて同じであっても、必ずこのオプションを指定するようにしておけば、後で桁数の異なる要素が追加されたとしても正常に動作します。

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 
*/

元の配列を変更しないソート(Array クラスのみ)

一般に、sort() および sortOn() メソッドを使用すると元の配列が変化します。既存の配列を変更せずにソートを実行する場合は、options パラメータに Array.RETURNINDEXEDARRAY 定数を含めます。このオプションを指定した場合、メソッドの戻り値はソート結果を示す新しい配列となり、元の配列の内容はそのまま維持されます。返される配列はソート後の並び順を示すインデックス番号だけを格納した単純なものであり、元の配列内の要素を格納した配列ではありません。例えば、poets 配列について元の状態を維持したまま生誕年でのソートを実行するには、options パラメータに Array.RETURNINDEXEDARRAY 定数を含めます。

次の例では、戻り値のインデックス情報を indices という配列に格納し、この indices と元のままの poets を使用して詩人のリストを生誕年順に表示しています。

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 
*/