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

JavaScriptで配列内の1を先頭へ、0を末尾へ分離する方法

JavaScriptでは、0・1・その他の数値が混在する配列に対して、「すべての1を配列の先頭に集め、すべての0を末尾に集めたい」という要件が発生することがあります。本記事では、このような配列の分離(セグリゲート)処理を実装する方法を解説します。

実装のポイント

今回のアプローチでは、以下の手順で処理を行います。

  • slice() で元の配列のコピーを作成し、元データを変更しないようにする
  • 配列を走査し、要素が 0 なら splice() で取り除いた後、push() で末尾へ移動する
  • 要素が 1 なら splice() で取り除いた後、unshift() で先頭へ移動する
  • それ以外の数値は元の位置にそのまま残す

コード例

const arr = [3, 2, 1, 8, 9, 0, 1, 9, 0, 2, 1, 0, 2, 0, 1, 0, 1, 1, 4, 0, 3];
const segregate = arr => {
    const copy = arr.slice();
    for(let i = 0; i < copy.length; i++){
        if(copy[i] === 0){
            copy.push(copy.splice(i, 1)[0]);
        }else if(copy[i] === 1){
            copy.unshift(copy.splice(i, 1)[0]);
        }
    }
    return copy;
};
console.log(segregate(arr));

出力結果

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

[
    1, 1, 1, 3, 2, 8, 9,
    1, 9, 2, 2, 1, 1, 4,
    3, 0, 0, 0, 0, 0, 0
]

コードの解説

ループ内で splice() を呼び出すたびに配列の長さと各要素のインデックスが変化することに注意してください。特に0を末尾へ移動した直後は後続の要素が1つ前に詰まるため、直後の要素が走査対象から外れる(スキップされる)ことがあります。そのため、上記の出力例のように一部の1が配列の中間に残る場合があります。

より堅牢な実装:filter()を活用する方法

インデックス操作による副作用を避けたい場合は、filter() で要素を振り分けてから連結する方法がシンプルで確実です。

const segregate = arr => {
    const ones = arr.filter(n => n === 1);
    const zeros = arr.filter(n => n === 0);
    const others = arr.filter(n => n !== 0 && n !== 1);
    return [...ones, ...others, ...zeros];
};

この実装では、すべての1が必ず先頭に、すべての0が必ず末尾に配置され、その他の数値は元の順序を保ったまま中間に並びます。計算量もO(n)で安定しており、可読性・保守性の面でも有利です。用途に応じて、両者の実装を使い分けるとよいでしょう。

  1. JavaScriptで配列内のすべてのピーク(局所最大値)とその位置を検出する方法

    データ分析や信号処理の現場では、数値の配列の中から「山」にあたる部分、つまり局所最大値(ピーク)とその位置を特定したい場面がよくあります。本記事では、JavaScriptを使って配列内のすべてのピークと、そのインデックス位置を効率的に検出する方法を解説します。 前提となる例 まず、次のようなJavaScriptの配列を用意します。 const arr = [4, 3, 4, 7, 5, 2, 3, 4, 3, 2, 3, 4]; この配列の各要素をY軸の値としてプロットし、隣り合う要素同士をX軸上で等間隔(単位距離)に配置すると、グラフは以下のようになります。 グラフを見ると分かるように、こ

  2. C言語で左矢印パターンと右矢印パターンを出力するプログラム

    プログラムの概要 このプログラムは、C言語を使って星(*)で構成された左矢印パターンと右矢印パターンをコンソールに出力します。ユーザーが行数を入力すると、その行数に応じた矢印の形が表示されます。for文の入れ子(二重ループ)の動きを学ぶのに最適な題材です。 アルゴリズム まず、矢印パターンを出力するための行数をユーザーから受け取ります。その後、次の手順でパターンを描画していきます。 星(*)で矢印の上半分を出力する 星(*)で逆右三角形を出力する 星(*)で矢印の下半分を出力する 星(*)で右三角形を出力する 左矢印パターンのロジック 左矢印パターンは2つのループで構成されます。前半のループ