JavaScriptで「#」の位置を固定したまま配列を反転させる方法
今回は、リテラル値の配列を受け取り、「#」が含まれているインデックスはそのまま維持しつつ、それ以外の要素だけを反転させて返すJavaScript関数を作成します。
たとえば、次のような配列が与えられた場合:
[18, -4, '#', 0, 8, '#', 5]
期待される出力は以下のとおりです。
[5, 8, "#", 0, -4, "#", 18]
ご覧のとおり、数値部分だけが逆順に並べ替えられ、「#」は元の位置(インデックス)に残ったままになっています。
解決のアプローチ
この問題は、次の3つのステップで解決できます。
- ステップ1:
reduce()を使って、「#」が存在するすべてのインデックス番号を収集します。 - ステップ2:
filter()で「#」を除外し、残りの数値だけの配列を作成してreverse()で反転します。 - ステップ3: 収集しておいたインデックスの位置に、
splice()を使って「#」を再挿入します。
コード例
const arr = [18, -4, '#', 0, 8, '#', 5];
const arr1 = [18, -4, 0, '#', 8, '#', 5];
const specialReverse = (arr = []) => {
// 「#」があるインデックスを収集
let removed = arr.reduce((acc, val, ind) => {
return val === '#' ? acc.concat(ind) : acc;
}, []);
// 「#」を除いた要素だけを反転
let reversed = arr.filter(val => val !== '#').reverse();
// 元の位置に「#」を戻す
removed.forEach(el => reversed.splice(el, 0, '#'));
return reversed;
};
console.log(specialReverse(arr));
console.log(specialReverse(arr1));
実行結果
コンソールには次のように出力されます。
[ 5, 8, '#', 0, -4, '#', 18 ] [ 5, 8, 0, '#', -4, '#', 18 ]
コードのポイント
この実装のポイントは、「除外」と「復元」を分けて考える点です。まず filter() と reverse() の組み合わせで対象となる要素だけを簡単に反転させ、その後 splice() で特別な要素を正確なインデックス位置に戻しています。
この手法は「#」以外にも、任意のマーカーやプレースホルダーを扱う場面に応用できるため、データ整形やパズル的なアルゴリズム課題で役立ちます。
-
JavaScriptで配列の要素を同じ配列内に複製する方法
JavaScriptでは、concat()メソッドとsort()メソッドを組み合わせることで、既存の配列の要素を同じ配列内に複製することができます。ここでは、実際に動作するサンプルコードを使って、その手順をわかりやすく解説します。 コード例 以下は、配列の要素を同じ配列内に複製するためのコード例です。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" cont
-
JavaScriptで元の配列を変更せずにオブジェクトのキー名を変更する方法
JavaScriptで配列内のオブジェクトのキー名(プロパティ名)を変更したい場合、deleteで直接削除してしまうと元のオブジェクトまで書き換わってしまいます。そこで役立つのが、map()メソッドとスプレッド構文(...)、分割代入を組み合わせたイミュータブル(非破壊的)な手法です。この記事では、オブジェクトのキー「name」を「fullName」に変更しながら、元の配列を一切変更しない方法をサンプルコード付きで解説します。サンプルコード<!DOCTYPE html> <html lang="ja"> <head> <meta c