Batで配列を操作する

私のバッチファイルの私のサッパーの投稿を読んでコードを実行した後、バッチファイルに配列がないというコメントに出会いました(ところで、その投稿で説明されているSapperの最新バージョンにはこのコメントがありません)。 そのため、バッチファイルで特定の値のセットを使用する必要がある場合、必要な変数の数を宣言してそれらを操作するのが論理的です。 実際、このシナリオはこの問題を簡単に解決するのに役立ちます。 以下に例を示します。

 echo配列Aを作成します。
 call:array new A "'one'、 'two'、 'three'、 'foo'、 'bar'"
 echo結果の3番目の要素を取得します。
呼び出し:配列はA 3の結果を取得します
 echo%result%
ヌル要素の変更をエコー
呼び出し:配列セットA 0 "最初の要素"


原理


配列はcall :array呼び出しを使用して処理され、適切なパラメーターを渡します。 最初のパラメーターはアクションで、2番目のパラメーターは配列の名前です。 これら2つにも、必須パラメーターとオプションパラメーターの両方を追加できます。 各配列は、 array_[ ]_[ ]形式の変数のセットと、サイズを含む1つの変数array_[ ]_countです。 これらの変数は手動で変更されないと想定されています。

配列の作成


配列を作成するにはいくつかの方法があります。 主なものはcreatenew 、およびloadです。
createメソッドは、指定されたサイズの配列を作成します。 デフォルトでゼロである初期値を設定することもできます。 それでも、値を空にすることはできません。これはsetコマンドの機能です。

rem call :array call :array create _ [=0] [ =0]

rem
call :array create myArray

rem , 5. - 0
call :array create myArray 5

rem , 5 "my value"
rem
call :array create myArray 5 "my value"


ただし、値を設定してすぐに配列を作成する方がはるかに便利です。 これを行うには、 新しいコマンドを使用します。

rem call :array new _ "1, 2, '' ..."

rem A 90, 56, ' '
call :array new A "90 56 ' '"


外部ファイルから値をロードできます。 ソースファイルは1251でエンコードする必要があり、現在のコードページはこれに影響しないことに注意してください。

rem call :array load _ _

rem records.txt Table. - .
call :array load Table records.txt


アイテムへのアクセス



各要素へのアクセスはインデックスによって可能です。 意味を返す手続きについてのいくつかの言葉。 なぜなら バッチファイルでは、プロシージャから値を返す方法はありません(呼び出しによって呼び出されるものと呼びます)、耳でフェイントを行う必要があります:結果が期待されるすべてのプロシージャは、変数_l(最後の単語のように小さい)に書き込みますその後、結果がより論理的になるようになり始めました)。 通常、変数名は最後のパラメーターに名前を渡すことで再定義できます。

rem call :array get _ [index=0] [__=_l]

rem myArray. _l
call :array get myArray
echo - %_l%

rem myArray ok
call :array get myArray -2 ok
echo : %ok%


デバッグ時には、多くの場合、値の迅速な出力が必要です。 これには、エコー (取得するエイリアス+エコー)およびダンプ (配列印刷)が役立ちます。
rem myArray
call :array echo myArray -1

rem
call :array dump myArray

印刷は次のようになります。
array[4]: myArray
[0]
[1]
[2] 3
[3]


リストを使用してアイテムを一覧表示すると、ファイルに保存できます。 残念ながら、他のチームにリダイレクトできませんでした。 例call :array list myArray | sort call :array list myArray | sortを行うと、「このファイルの外部からバッチファイルのラベルにジャンプしようとする無効な試み」というエラーが発生します。
call :array list myArray > output.txt

countコマンドは、要素の数を取得するために使用されます(基本的に、変数array_[ ]_countから読み取りますが、追加の存在チェックなどを使用します。
call :array count myArray len
echo %len% .


findは、最初に見つかった要素のインデックスを返します。一致するものがない場合は-1を返します。 いわゆるフラグがここに表示されます。 これらはパラメータである場合とそうでない場合があります。 通常は最後になりますが、その後に結果の変数名を指定できる場合があり、その場合はどうすればよいかという疑問が生じる場合があります。 この場合、フラグは必要ないが、変数を設定する必要がある場合は、湿気の位置で他の値、たとえば格子番号#またはマイナス-を指定するだけです。 さて、例で示します。

rem call :array find _ _ N [__=_l]
rem N - I. , N .
rem sebastNum , .
call :array find myArr " " N sebastNum

rem :
call :array find myArr " " I sebastNum

rem _l:
call :array find myArr " "


配列操作



これまで、インデックスによる要素値の設定、要素の削除、配列のコピー、配列の削除、要素の追加を実装しました。

それでも、セットについて話す必要があります。 一部のプロシージャには、パラメータとしてセットを渡すことができます。 これらのセットは、処理のためにforコマンドに渡されるため、必要に応じてこのように記述する必要があります。 ただし、要求は厳しくありません。セットの要素はコンマ(、)またはスペース()で区切られ、文字列は引用符で囲む必要があります。 しかし、以来 パラメーター自体も二重引用符で囲まれているため、セットには単一( ')が必要です。 追加例を参照してください。

rem
rem call :array set _
call :array set myArray 5 ' '

rem
rem call :array copy _ _
call :array copy myArray finalArray

rem
rem call :array add _
rem call :array add myArray 2012

rem . , , , ! -
rem call :add _ !
call :array add myArray "' ' 120 454.34 'sd'" !
rem expand "!"
call :array expand myArray "' ' 120 454.34 'sd'"

rem
rem call :array del _ [_| = ]

rem ( del) , -
rem myArr 9
call :array del myArr 9

rem ,
rem myArr 4, 6 8
call :array del myArr "4,6,8"

rem ,
call :array del myArr


追加機能



私の意見では、これらは最も興味深い操作です。 それらは操作に起因する可能性がありますが、私はそれらを別々に分けることにしました。

cp1251エンコーディングでファイルに保存する



上記のように、リスト出力リダイレクトを使用して、ファイルへの保存を実装できます。 ただし、cp1251エンコーディングでファイルを保存する必要がある場合は、saveコマンドを使用することをお勧めします。
rem call :array save _ _

call :array save results .txt


配列ソート



sortコマンドによって実行されます。 通常のバブルでソートを実装することはできましたが、ソートコマンドのヘルプを引き続き使用することにしました。 しかし、このアプローチにはいくつかのマイナス点があります:一時ディレクトリに2つのファイルが作成され(配列がスローされ、並べ替えられますが、それでも削除されます)、数字は文字列として並べ替えられます。 真実も2つのプラスです:私には思えますが、速度は追いませんでしたが(それは一連のインデックスでdel操作から見ることができます)、シンプルですが、これは完全にこの方法を選択することにつながりました。

rem call :array sort _ [R - ]

rem myArray
call :array sort myArray R


各アイテムに手順を適用する



各コマンドが使用され、2つのアプローチがあります。 1つは、コマンドの直接転送です。 この場合、現在の要素のインデックスに_i_置換を使用し、その値に_val_置換を使用できます。 コマンドを渡すことをスクリプトに理解させるには、最後のパラメーターx(x)を指定します

call :array new B "1 4 1 6 7 2"
set sum=0
call :array each B "set /a sum+=_val_" x
rem sum ( )


2番目のアプローチは、各要素に対して呼び出されるラベルを示すことです: call :__ 。 最初の方法が単純な場合、これはより柔軟なオプションを提供します。 例:

rem
call :array new someArray "1902 2007 2012 1954 1945 1989"

rem
set pos=0
call :array get someArray %pos% val

rem findMax
call :array each someArray findMax

rem
echo %val%. %pos%

goto :eof

:findMax
rem %~1 - ( , ~)~, %2 - .

if %~1 GTR %val% (
set val=%~1
set pos=%2
)

goto :eof


サポート手順



いくつかの操作を実装するために、いくつかの別個の手順が使用されます(これらは、配列を介して呼び出されません。これが意味するものです)。 彼らはまた興味深いように見えるかもしれません:


ダウンロードする



Google Docsまたはpastebin.comで コード確認できます

ありがとう、今は本当に便利なことができます。

Source: https://habr.com/ru/post/J75951/


All Articles