arrayRotateアレイローテート関数

本ページには広告が含まれています。

配列をshiftの値だけ後ろに循環シフトさせます。後ろにシフトしてはみ出た分は配列の先頭に格納されます。

構文
arrayRotate( array, shift )
引数
array 必須
配列
shift 必須
シフトする要素数。正の数で末尾方向。負の数で先頭方向。
戻り値

プログラム

UWSC
//////////////////////////////////////////////////
// 【引数】
//   array : 配列 
//   shift : シフトする要素数。正の数で末尾方向。負の数で先頭方向。 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arrayRotate(array[], shift)
	IF shift < 0 THEN shift = LENGTH(array) + shift
	DIM array1 = arraySlice(array, shift)
	DIM array2 = arraySlice(array, 0, shift)
	arrayMerge(array1, array2)
	RESULT = array1
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 一次元配列。参照引数。 
//   callback : コールバック関数。callback内で配列の値は「%val%」で使うことができます。 
// 【戻り値】
//   
//////////////////////////////////////////////////
PROCEDURE arrayFilter(var array[], callback)
	DIM n = 0
	DIM tmp[-1]
	FOR %val% IN array
		IFB EVAL(callback) THEN
			RESIZE(tmp, n)
			tmp[n] = %val%
			n = n + 1
		ENDIF
	NEXT
	RESIZE(array, RESIZE(tmp))
	FOR n = 0 TO RESIZE(tmp)
		array[n] = tmp[n]
	NEXT
FEND

//////////////////////////////////////////////////
// 【引数】
//   arr : 追加される配列(参照引数) 
//   tmp : 追加する配列 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arrayMerge(Var arr[], tmp[])
	FOR n = 0 TO UBound(tmp)
		arrayPush(arr, tmp[n])
	NEXT
	RESULT = UBound(arr)
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 要素を追加する配列(参照引数) 
//   values : 追加する要素をvalue1から指定 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arrayPush(var array[], value1 = EMPTY, value2 = EMPTY, value3 = EMPTY, value4 = EMPTY, value5 = EMPTY, value6 = EMPTY, value7 = EMPTY, value8 = EMPTY, value9 = EMPTY, value10 = EMPTY, value11 = EMPTY, value12 = EMPTY, value13 = EMPTY, value14 = EMPTY, value15 = EMPTY, value16 = EMPTY)
    DIM i = 1
    WHILE EVAL("value" + i) <> EMPTY
	  DIM res = RESIZE(array, UBound(array) + 1)
	  array[res] = EVAL("value" + i)
	  i = i + 1
	WEND
	RESULT = LENGTH(array)
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 配列 
//   offset : 配列の位置。負の値の場合、配列の後ろから 
//   length : lengthが省略された場合は末尾まで。lengthが正の数ならば、offsetからlengthの数だけ要素を取得。lengthが負の数ならば、末尾からlengthだけ切り捨てる。 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arraySlice(array[], offset, length = NULL)
	SELECT TRUE
		CASE offset > 0
			SHIFTARRAY(array, -1 * offset)
			IF length = NULL THEN length = LENGTH(array) - offset
			RESIZE(array, length - 1)
		CASE offset < 0
			SHIFTARRAY(array, ABS(offset) - LENGTH(array))
			RESIZE(array, LENGTH(array) - ABS(offset))
			arrayFilter(array, "%val% <> EMPTY")
			IF length < 0 THEN RESIZE(array, RESIZE(array) + length)
		CASE offset = 0
			IF length = NULL THEN length = LENGTH(array)
			RESIZE(array, length - 1)
	SELEND
	RESULT = SLICE(array)
FEND

//////////////////////////////////////////////////
// 【引数】
//   inputs : 繰り返す文字列 
//   multiplier : inputsを繰り返す回数 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION strRepeat(inputs, multiplier)
	DIM res = ""
	FOR n = 1 TO multiplier
		res = res + inputs
	NEXT
	RESULT = res
FEND

//////////////////////////////////////////////////
// 【引数】
//   arrayname : 上限値を求める配列の名前 
//   dimension : 返す次元を示す整数 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION UBound(arrayname[], dimension = 1)
	RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")")
FEND

プログラム実行例

キーボードからの入力を1文字ずつずらす

キーからのABBC、…、ZAのように1文字後ろにずらします。

UWSC
SETHOTKEY(VK_ESC, EMPTYPARAM, "forceQuit")

PUBLIC array[-1]

FOR key = VK_A TO VK_Z
	arrayPush(array, key)
NEXT

PUBLIC rotate
rotate = arrayRotate(array, 1)

PUBLIC key

FOR key = VK_A TO VK_Z
	SETHOTKEY(key,, "keyChange")
	SETHOTKEY(key, MOD_SHIFT, "keyChange")
NEXT

WHILE TRUE
	FUKIDASI("キー割り当て変更中。ESCで終了")
	SLEEP(0.001)
WEND

PROCEDURE keyChange()
	DIM vk = rotate[arraySearch(HOTKEY_VK, array)]
	IFB HOTKEY_MOD = 4 THEN
		vk = STRCONV(vk, SC_UPPERCASE)
	ENDIF
	KBD(vk)
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 一次元配列。参照引数。 
//   callback : コールバック関数。callback内で配列の値は「%val%」で使うことができます。 
// 【戻り値】
//   
//////////////////////////////////////////////////
PROCEDURE arrayFilter(var array[], callback)
	DIM n = 0
	DIM tmp[-1]
	FOR %val% IN array
		IFB EVAL(callback) THEN
			RESIZE(tmp, n)
			tmp[n] = %val%
			n = n + 1
		ENDIF
	NEXT
	RESIZE(array, RESIZE(tmp))
	FOR n = 0 TO RESIZE(tmp)
		array[n] = tmp[n]
	NEXT
FEND

//////////////////////////////////////////////////
// 【引数】
//   arr : 追加される配列(参照引数) 
//   tmp : 追加する配列 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arrayMerge(Var arr[], tmp[])
	FOR n = 0 TO UBound(tmp)
		arrayPush(arr, tmp[n])
	NEXT
	RESULT = UBound(arr)
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 要素を追加する配列(参照引数) 
//   values : 追加する要素をvalue1から指定 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arrayPush(var array[], value1 = EMPTY, value2 = EMPTY, value3 = EMPTY, value4 = EMPTY, value5 = EMPTY, value6 = EMPTY, value7 = EMPTY, value8 = EMPTY, value9 = EMPTY, value10 = EMPTY, value11 = EMPTY, value12 = EMPTY, value13 = EMPTY, value14 = EMPTY, value15 = EMPTY, value16 = EMPTY)
    DIM i = 1
    WHILE EVAL("value" + i) <> EMPTY
	  DIM res = RESIZE(array, UBound(array) + 1)
	  array[res] = EVAL("value" + i)
	  i = i + 1
	WEND
	RESULT = LENGTH(array)
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 配列 
//   shift : シフトする要素数。正の数で末尾方向。負の数で先頭方向。 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arrayRotate(array[], shift)
	IF shift < 0 THEN shift = LENGTH(array) + shift
	DIM array1 = arraySlice(array, shift)
	DIM array2 = arraySlice(array, 0, shift)
	arrayMerge(array1, array2)
	RESULT = array1
FEND

//////////////////////////////////////////////////
// 【引数】
//   needle : 検索する値 
//   haystack : 配列 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arraySearch(needle, haystack[])
	DIM i = 0
	FOR item IN haystack
		IFB item = needle THEN
			RESULT = i
			EXIT
		ENDIF
		i = i + 1
	NEXT
FEND

//////////////////////////////////////////////////
// 【引数】
//   array : 配列 
//   offset : 配列の位置。負の値の場合、配列の後ろから 
//   length : lengthが省略された場合は末尾まで。lengthが正の数ならば、offsetからlengthの数だけ要素を取得。lengthが負の数ならば、末尾からlengthだけ切り捨てる。 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION arraySlice(array[], offset, length = NULL)
	SELECT TRUE
		CASE offset > 0
			SHIFTARRAY(array, -1 * offset)
			IF length = NULL THEN length = LENGTH(array) - offset
			RESIZE(array, length - 1)
		CASE offset < 0
			SHIFTARRAY(array, ABS(offset) - LENGTH(array))
			RESIZE(array, LENGTH(array) - ABS(offset))
			arrayFilter(array, "%val% <> EMPTY")
			IF length < 0 THEN RESIZE(array, RESIZE(array) + length)
		CASE offset = 0
			IF length = NULL THEN length = LENGTH(array)
			RESIZE(array, length - 1)
	SELEND
	RESULT = SLICE(array)
FEND

//////////////////////////////////////////////////
// 【引数】
//   
// 【戻り値】
//   
//////////////////////////////////////////////////
PROCEDURE forceQuit()
	EXITEXIT
FEND

//////////////////////////////////////////////////
// 【引数】
//   inputs : 繰り返す文字列 
//   multiplier : inputsを繰り返す回数 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION strRepeat(inputs, multiplier)
	DIM res = ""
	FOR n = 1 TO multiplier
		res = res + inputs
	NEXT
	RESULT = res
FEND

//////////////////////////////////////////////////
// 【引数】
//   arrayname : 上限値を求める配列の名前 
//   dimension : 返す次元を示す整数 
// 【戻り値】
//   
//////////////////////////////////////////////////
FUNCTION UBound(arrayname[], dimension = 1)
	RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")")
FEND
使用関数