UWSCで連想配列を配列にする
UWSCの連想配列(HASHTBL)は、配列に入れられない。
関数の返り値にもできない。
これが、たま〜に、もどかしい。
ということで、考えてみた。
とりあえず結論
javascriptでやりますか。
HashObj.uws
OPTION EXPLICIT IFB GET_UWSC_NAME = "HashObj.uws" THEN DIM pets = HashObj.Create(TRUE), i pets.Set("Brown", "Dog") pets.Set("Black", "Cat") PRINT "I love " + pets.Get("Brown") IF pets.Exists("Brown") THEN PRINT "Buy dog foods." IF MSGBOX("Is Black alive?", BTN_YES OR BTN_NO) = BTN_NO THEN ret = pets.Remove("Black") FOR i = 0 TO pets.Length() - 1 PRINT pets.Key(i) + " " + pets.Val(i) NEXT pets.RemoveAll() // 配列化試験 DIM d[9] FOR i = 0 TO LENGTH(d) - 1 d[i] = HashObj.Create() d[i].Set(1, "test") NEXT FOR i = 0 TO LENGTH(d) - 1 IF d[i].Get(1) <> "test" THEN PRINT "NG: d[" + i + "].Get(1): " + d[i].Get(1) d[i].RemoveAll() NEXT HashObj.Dispose() ENDIF MODULE HashObj DIM _sct TEXTBLOCK _JS_SRC var HashObj = function(bcase, bsort) { this._keys = new Array() this._case = bcase this._sort = bsort this.KeyConv = function(key) { var ret = key if(this._case == 0 && (typeof key == "string" || key instanceof String)) { ret = key.toUpperCase() } return ret } this.Get = function(key) { return this[this.KeyConv(key)] } this.Set = function(key, val) { var n = this.KeyConv(key) for(var i = 0; i < this._keys.length; i++) { if(this.KeyConv(this._keys[i]) == n) { this[n] = val n = "" } } if((typeof n != "string" && !(n instanceof String)) || n.length > 0) { this._keys[this._keys.length] = key if(this._sort == 1) this._keys.sort() this[n] = val } } this.Key = function(index) { return this._keys[index] } this.Val = function(index) { return this[this.KeyConv(this.Key(index))] } this.Length = function() { return this._keys.length } this.Exists = function(key) { return (this.KeyConv(key) in this) } this.Remove = function(key) { key = this.KeyConv(key) var ret = false for(var i = 0; i < this._keys.length; i++) { if(this.KeyConv(this._keys[i]) == key) { this._keys.splice(i, 1) ret = true } } delete this[key] return ret } this.RemoveAll = function() { for(var i = 0; i < this._keys.length; i++) { delete this[this.KeyConv(this._keys[i])] } this._keys = new Array() } } ENDTEXTBLOCK PROCEDURE HashObj _sct = CREATEOLEOBJ("ScriptControl") _sct.Language = "JScript" _sct.ExecuteStatement(_JS_SRC) FEND PROCEDURE Dispose() _sct.Reset() _sct = Nothing FEND FUNCTION Create(bCase=FALSE, bSort=FALSE, name="HashObj") DIM c = 0, s = 0 IF bCase THEN c = 1 IF bSort THEN s = 1 RESULT = _sct.Eval("new " + name + "(" + c + "," + s + ")") FEND ENDMODULE
使い方
以下のような場合
HASHTBL pets = HASH_CASECARE pets["Brown"] = "Dog" pets["Black"] = "Cat" PRINT "I love " + pets["Brown"] IF pets["Brown", HASH_EXISTS] THEN PRINT "Buy dog foods." IF MSGBOX("Is Black alive?", BTN_YES OR BTN_NO) = BTN_NO THEN ret = pets["Black", HASH_REMOVE] FOR i = 0 TO LENGTH(pets) - 1 PRINT pets[i, HASH_KEY] + " " + pets[i, HASH_VAL] NEXT pets = HASH_REMOVEALL
テスト用コードにあるように、以下のように変えます。
CALL HashObj DIM pets = HashObj.Create(TRUE) pets.Set("Brown", "Dog") pets.Set("Black", "Cat") PRINT "I love " + pets.Get("Brown") IF pets.Exists("Brown") THEN PRINT "Buy dog foods." IF MSGBOX("Is Black alive?", BTN_YES OR BTN_NO) = BTN_NO THEN ret = pets.Remove("Black") FOR i = 0 TO pets.Length() - 1 PRINT pets.Key(i) + " " + pets.Val(i) NEXT pets.RemoveAll()
HashObj.Createの第一引数がHASH_CASECAREで、第二引数がHASH_SORT。
設定と取得に、Setメソッド/Getメソッドというのがダサいですが、、、。
配列に入れられるし、RESULTにも設定できるので、許してくださいな。