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

JavaScriptでアナグラム配列同士のインデックスをマッピングする方法


アナグラム配列とは

ある配列の要素を並べ替えることで、もう一方の配列とまったく同じ並びを作れる場合、その2つの配列は「互いのアナグラム」であると言えます。

例えば、次のような関係です。

[1, 2, 3] と [2, 1, 3] は互いにアナグラムです。

ここで、互いにアナグラムの関係にある2つの配列 arr1arr2 が与えられたとします。

求められているのは、この2つの配列を受け取り、arr1 と同じ長さの新しい「マッピング配列」を返すJavaScript関数です。マッピング配列には、arr1 の各要素が arr2 のどのインデックス位置に存在するかを格納します。

入力例

例えば、入力が次の2つの配列だった場合:

const arr1 = [23, 39, 57, 43, 61];
const arr2 = [61, 23, 43, 57, 39];

出力は次のようになります。

const output = [1, 4, 3, 2, 0];

これは、arr1 のインデックス0にある要素(23)が arr2 ではインデックス1に位置し、インデックス1にある要素(39)は arr2 のインデックス4に位置する――といった対応関係を表しています。以降も同様に、すべての要素について位置関係が記録されます。

実装例

最もシンプルなのは、二重ループで各要素の位置を探す方法です。

const arr1 = [23, 39, 57, 43, 61];
const arr2 = [61, 23, 43, 57, 39];
const anagramMappings = (arr1 = [], arr2 = []) => {
    const res = [];
    for(let i = 0; i < arr1.length; i++) {
        for(let j = 0; j < arr2.length; j++) {
            if(arr1[i] == arr2[j]){
                res.push(j);
            };
        };
    };
    return res;
};
console.log(anagramMappings(arr1, arr2));

より簡潔な書き方(map + indexOf)

Array.prototype.map()indexOf() を組み合わせると、同じ処理を1行で表現できます。

const anagramMappings = (arr1 = [], arr2 = []) =>
    arr1.map(el => arr2.indexOf(el));

さらに、要素数が多い配列に対しては、Map を使って arr2 の値とインデックスを事前に登録しておくことで、計算量 O(n²) の二重ループを O(n) まで高速化できます。

const anagramMappings = (arr1 = [], arr2 = []) => {
    const indexMap = new Map();
    arr2.forEach((val, idx) => indexMap.set(val, idx));
    return arr1.map(el => indexMap.get(el));
};

出力結果

いずれの方法でも、コンソールには次のように出力されます。

[ 1, 4, 3, 2, 0 ]

  1. JavaScriptのMap(マップ)オブジェクトとは?基本的な使い方をサンプルコード付きで解説

    MapオブジェクトとはMap(マップ)オブジェクトは、ES6(ECMAScript 2015)で導入された組み込みオブジェクトの一つで、「キー」と「値」のペアで構成される要素を管理するコレクションです。通常のオブジェクトとよく似ていますが、Mapの大きな特徴は、キーにオブジェクトやプリミティブ値など、あらゆる型の値を使用できる点にあります。さらに、要素は挿入した順序で保持されるため、for...ofループなどを利用して、追加した順番どおりに反復処理を行うことも可能です。Mapオブジェクトの主なメソッドとプロパティメソッド / プロパティ説明new Map(iterable)配列などのイテラブル

  2. JavaScriptである関数から別の関数へイベントオブジェクトを渡す方法

    JavaScriptでは、イベントハンドラ内で取得したイベントオブジェクトを、そのまま引数として別の関数へ渡すことができます。イベントオブジェクトには発生元の要素(event.target)やイベントの種類などの情報が含まれているため、複数の関数で同じイベント情報を共有したい場合にとても便利です。以下は、クリックイベントのイベントオブジェクトを受け渡し、ボタンのフォントサイズと文字色を変更するサンプルコードです。サンプルコード<!DOCTYPE html> <html lang="en"> <head> <meta charset=