JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

【JavaScript】別の文字列配列を基準にオブジェクト配列を並べ替える方法

例えば、id プロパティの順に並んだ次のようなオブジェクトの配列があるとします。

const unordered = [{
    id: 1,
    string: 'sometimes'
}, {
    id: 2,
    string: 'be'
}, {
    id: 3,
    string: 'can'
}, {
    id: 4,
    string: 'life'
}, {
    id: 5,
    string: 'tough'
}, {
    id: 6,
    string: 'very'
}];

さらに、希望する並び順を表す次のような文字列の配列があるとしましょう。

const ordered = ['life', 'sometimes', 'can', 'be', 'very', 'tough'];

このとき、最初の配列の string プロパティが、2番目の配列とまったく同じ順序になるように並べ替えたい、というのが今回の課題です。
それでは、具体的なコードを見ていきましょう。

indexOf を使った基本的な方法

Array.prototype.sort() の比較関数の中で、各要素の string 値が基準となる配列の何番目にあるのかを indexOf() で調べ、その位置の差によって順序を決定します。

const unordered = [{
    id: 1,
    string: 'sometimes'
}, {
    id: 2,
    string: 'be'
}, {
    id: 3,
    string: 'can'
}, {
    id: 4,
    string: 'life'
}, {
    id: 5,
    string: 'tough'
}, {
    id: 6,
    string: 'very'
}];

const ordered = ['life', 'sometimes', 'can', 'be', 'very', 'tough'];

const sorter = (a, b) => {
    return ordered.indexOf(a.string) - ordered.indexOf(b.string);
};

unordered.sort(sorter);
console.log(unordered);

実行結果

コンソールには次のように出力されます。

[
    { id: 4, string: 'life' },
    { id: 1, string: 'sometimes' },
    { id: 3, string: 'can' },
    { id: 2, string: 'be' },
    { id: 6, string: 'very' },
    { id: 5, string: 'tough' }
]

string プロパティが基準配列と同じ順序(life → sometimes → can → be → very → tough)に並び替えられていることが確認できます。

パフォーマンスを改善するには

indexOf() は配列の先頭から順に対象を探すため、1回の参照につき O(n) の計算量がかかります。データ件数が多い場合は、あらかじめ Map で「文字列 → インデックス」の対応表を作成しておくと、O(1) で参照できて高速です。

const orderMap = new Map(ordered.map((str, index) => [str, index]));

const sorter = (a, b) => {
    return orderMap.get(a.string) - orderMap.get(b.string);
};

unordered.sort(sorter);

大文字・小文字の扱いに注意

JavaScript の文字列比較は大文字・小文字を区別します。基準配列側に 'Life' のように大文字が混ざっていると indexOf() は一致を検出できず、-1 が返されて意図しない順序になる恐れがあります。確実にマッチさせたい場合は、toLowerCase() などで両者を正規化してから比較するのが安全です。

  1. JavaScriptで文字列を配列の指定順序どおりにシャッフルする方法

    本記事では、文字列 str を第一引数として、それと同じ長さの正の整数の配列 arr を第二引数として受け取る JavaScript 関数の実装方法を解説します。この関数は、文字列内の文字を並べ替え(シャッフル)し、i 番目の位置にある文字が、シャッフル後の文字列の arr[i] 番目の位置へ移動するようにします。入力例と期待される出力たとえば、次の文字列と配列が与えられたとします。const str = example; const arr = [5, 2, 0, 6, 4, 1, 3];この場合、期待される出力は次のとおりです。const output = alxepem;各文字がどのよう

  2. JavaScriptで配列の値に基づいて文字列の文字をシフトする方法

    本記事では、小文字の英字のみで構成された文字列に対して、配列内の数値に従って各文字をシフトするJavaScript関数の実装方法を解説します。 問題の概要 まず、「1単位のシフト」を次のように定義します。ある文字を、アルファベット順でその直後の文字に置き換えること。これには循環(ラップアラウント)も含まれます。つまり、「z」の次の文字は「a」となります。 今回作成する関数は、以下の2つの引数を受け取ります。 str: 小文字英字のみを含む文字列(第1引数) arr: strと同じ長さを持つ数値の配列(第2引数) 関数は、元の文字列の各文字を、配列arr内の同じ位置にある数値の分だけ