OSDN Git Service

87094894d83d810dd9e4f1b5edb33be6c5295924
[chnosproject/AI004.git] / aiext.js
1 //
2 // クラス拡張
3 //
4
5 //継承機能
6 Function.prototype.extend = function(baseConstructor, newPrototype){
7         // http://sourceforge.jp/projects/h58pcdgame/scm/git/GameScriptCoreLibrary/blobs/master/www/corelib/jsbase.js
8         //最初にベースクラスのプロトタイプを引き継ぐ。
9         var F = function(){};
10         F.prototype = baseConstructor.prototype;
11         this.prototype = new F();
12         //新たなプロトタイプを追加・上書きする。
13         if(newPrototype){
14                 for(var prop in newPrototype){
15                         this.prototype[prop] = newPrototype[prop];
16                 }
17         }
18         //コンストラクタを設定
19         this.prototype.constructor = this;
20         //ベースクラスのコンストラクタを設定
21         this.base = baseConstructor;
22         return this;
23 };
24
25 //配列関連
26 Array.prototype.removeAllObject = function(anObject){
27         //Array中にある全てのanObjectを削除し、空いた部分は前につめる。
28         //戻り値は削除が一回でも実行されたかどうか
29         var ret = false;
30         for(var i = 0; i < this.length; i++){
31                 if(this[i] == anObject){
32                         this.splice(i, 1);
33                         ret = true;
34                         i--;
35                 }
36         }
37         return ret;
38 }
39 Array.prototype.removeAnObject = function(anObject){
40         //Array中にある最初のanObjectを削除し、空いた部分は前につめる。
41         //戻り値は削除が実行されたかどうか
42         for(var i = 0; i < this.length; i++){
43                 if(this[i] == anObject){
44                         this.splice(i, 1);
45                         return true;
46                 }
47         }
48         return false;
49 }
50 Array.prototype.removeByIndex = function(index){
51         //Array[index]を削除し、空いた部分は前につめる。
52         this.splice(index, 1);
53         return;
54 }
55 Array.prototype.intersectionWith = function(a, b, fEqualTo){
56         //積集合を求める
57         //fEqualToは省略可能で、評価関数fEqualTo(a[i], b[j])を設定する。
58         var r = new Array();
59         for(var i = 0, len = b.length; i < len; i++){
60                 if(this.isIncluded(b[i], fEqualTo)){
61                         r.push(b[i]);
62                 }
63         }
64         return r;
65 }
66 Array.prototype.unionWith = function(a, b, fEqualTo){
67         //和集合を求める
68         //fEqualToは省略可能で、評価関数fEqualTo(a[i], b[j])を設定する。
69         var r = new Array();
70         for(var i = 0, len = b.length; i < len; i++){
71                 if(!this.isIncluded(b[i], fEqualTo)){
72                         r.push(b[i]);
73                 }
74         }
75         return this.concat(r);
76 }
77 Array.prototype.isIncluded = function(obj, fEqualTo){
78         //含まれている場合は配列内のそのオブジェクトを返す
79         //fEqualToは省略可能で、評価関数fEqualTo(array[i], obj)を設定する。
80         if(fEqualTo == undefined){
81                 for(var i = 0, len = this.length; i < len; i++){
82                         if(this[i] == obj){
83                                 return this[i];
84                         }
85                 }
86         } else{
87                 for(var i = 0, len = this.length; i < len; i++){
88                         if(fEqualTo(this[i], obj)){
89                                 return this[i];
90                         }
91                 }
92         }
93         return false;
94 }
95 Array.prototype.search2DLineIndex = function(column, obj, fEqualTo){
96         //与えられた配列を二次元配列として解釈し
97         //array[n][column]がobjと等価になる最初の行nを返す。
98         //fEqualToは省略可能で、評価関数fEqualTo(array[n][column], obj)を設定する。
99         //該当する行がなかった場合、戻り値はundefinedとなる。
100         if(fEqualTo == undefined){
101                 for(var i = 0, iLen = this.length; i < iLen; i++){
102                         if(this[i] instanceof Array && this[i][column] == obj){
103                                 return i;
104                         }
105                 }
106         } else{
107                 for(var i = 0, iLen = this.length; i < iLen; i++){
108                         if(this[i] instanceof Array && fEqualTo(this[i][column], obj)){
109                                 return i;
110                         }
111                 }
112         }
113         return undefined;
114 }
115 Array.prototype.search2DObject = function(searchColumn, retvColumn, obj, fEqualTo){
116         //与えられた配列を二次元配列として解釈し
117         //array[n][searchColumn]がobjと等価になる最初の行のオブジェクトarray[n][retvColumn]を返す。
118         //fEqualToは省略可能で、評価関数fEqualTo(array[n][searchColumn], obj)を設定する。
119         //該当する行がなかった場合、戻り値はundefinedとなる。
120         if(fEqualTo == undefined){
121                 for(var i = 0, iLen = this.length; i < iLen; i++){
122                         if(this[i] instanceof Array && this[i][searchColumn] == obj){
123                                 return this[i][retvColumn];
124                         }
125                 }
126         } else{
127                 for(var i = 0, iLen = this.length; i < iLen; i++){
128                         if(this[i] instanceof Array && fEqualTo(this[i][searchColumn], obj)){
129                                 return this[i][retvColumn];
130                         }
131                 }
132         }
133         return undefined;
134 }
135 Array.prototype.pushUnique = function(obj, fEqualTo){
136         //値が既に存在する場合は追加しない。評価関数fEqualTo(array[i], obj)を設定することができる。
137         //結果的に配列内にあるオブジェクトが返される。
138         var o = this.isIncluded(obj, fEqualTo);
139         if(!o){
140                 this.push(obj);
141                 return obj;
142         }
143         return o;
144 }
145 Array.prototype.stableSort = function(f){
146         // http://blog.livedoor.jp/netomemo/archives/24688861.html
147         // Chrome等ではソートが必ずしも安定ではないので、この関数を利用する。
148         if(f == undefined){
149                 f = function(a,b){ return a - b; };
150         }
151         for(var i = 0; i < this.length; i++){
152                 this[i].__id__ = i;
153         }
154         this.sort.call(this, function(a,b){
155                 var ret = f(a, b);
156                 if(ret == 0){
157                         return (a.__id__ > b.__id__) ? 1 : -1;
158                 } else{
159                         return ret;
160                 }
161         });
162         for(var i = 0;i < this.length;i++){
163                 delete this[i].__id__;
164         }
165 }
166 Array.prototype.splitByArray = function(separatorList){
167         //Array中の文字列をseparatorList内の文字列でそれぞれで分割し、それらの文字列が含まれた配列を返す。
168         var retArray = new Array();
169         
170         for(var i = 0, iLen = this.length; i < iLen; i++){
171                 retArray = retArray.concat(this[i].splitByArray(separatorList));
172         }
173         
174         return retArray;
175 }
176 Array.prototype.propertiesNamed = function(pName){
177         //Array内の各要素のプロパティpNameのリストを返す。
178         var retArray = new Array();
179         for(var i = 0, iLen = this.length; i < iLen; i++){
180                 retArray.push(this[i][pName]);
181         }
182         return retArray;
183 }
184 Array.prototype.logAsHexByte = function(){
185         //十六進バイト列としてデバッグ出力する。
186         var ds = "";
187         for(var i = 0, iLen = this.length; i < iLen; i++){
188                 ds += ("00" + this[i].toString(16).toUpperCase()).slice(-2);
189         }
190         console.log(ds);
191 }
192 Array.prototype.stringAsHexByte = function(){
193         //十六進バイト列として文字列を得る
194         var ds = "";
195         for(var i = 0, iLen = this.length; i < iLen; i++){
196                 ds += ("00" + this[i].toString(16).toUpperCase()).slice(-2);
197         }
198         return ds;
199 }
200 Array.prototype.logEachPropertyNamed = function(pname, logfunc, suffix){
201         //Arrayのすべての各要素pについて、プロパティp[pname]を文字列としてlogfuncの引数に渡して呼び出す。
202         //suffixは各文字列の末尾に追加する文字列。省略時は改行文字となる。
203         //logfuncは省略時はconsole.logとなる。
204         if(logfunc === undefined){
205                 logfunc = function(s){ console.log(s); };
206         }
207         if(suffix === undefined){
208                 suffix = "\n";
209         }
210         for(var i = 0, iLen = this.length; i < iLen; i++){
211                 logfunc(this[i][pname] + suffix);
212         }
213 }
214 Array.prototype.copy = function(){
215         return (new Array()).concat(this);
216 }
217
218 //文字列関連
219 String.prototype.replaceAll = function(org, dest){
220         //String中にある文字列orgを文字列destにすべて置換する。
221         //http://www.syboos.jp/webjs/doc/string-replace-and-replaceall.html
222         return this.split(org).join(dest);
223 }
224 String.prototype.compareLeftHand = function (search){
225         //前方一致長を求める。
226         for(var i = 0; search.charAt(i) != ""; i++){
227                 if(search.charAt(i) != this.charAt(i)){
228                         break;
229                 }
230         }
231         return i;
232 }
233 String.prototype.splitByArray = function(separatorList){
234         //リスト中の文字列それぞれで分割された配列を返す。
235         //separatorはそれ以前の文字列の末尾に追加された状態で含まれる。
236         //"abcdefg".splitByArray(["a", "e", "g"]);
237         //      = ["a", "bcde", "fg"]
238         var retArray = new Array();
239         retArray[0] = this;
240         
241         for(var i = 0; i < separatorList.length; i++){
242                 var tmpArray = new Array();
243                 for(var k = 0; k < retArray.length; k++){
244                         tmpArray[k] = retArray[k].split(separatorList[i]);
245                         if(tmpArray[k][tmpArray[k].length - 1] == ""){
246                                 tmpArray[k].splice(tmpArray[k].length - 1, 1);
247                                 if(tmpArray[k] && tmpArray[k].length > 0){
248                                         for(var m = 0; m < tmpArray[k].length; m++){
249                                                 tmpArray[k][m] += separatorList[i];
250                                         }
251                                 }
252                         } else{
253                                 for(var m = 0; m < tmpArray[k].length - 1; m++){
254                                         tmpArray[k][m] += separatorList[i];
255                                 }
256                         }
257                 }
258                 retArray = new Array();
259                 retArray = retArray.concat.apply(retArray, tmpArray);
260         }
261         
262         if(retArray.length == 0){
263                 // https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split
264                 //文字列が空であるとき、split メソッドは、空の配列ではなく、1 つの空文字列を含む配列を返します。
265                 retArray.push("");
266         }
267         
268         return retArray;
269 }
270
271 String.prototype.splitByArraySeparatorSeparated = function(separatorList){
272         //リスト中の文字列それぞれで分割された配列を返す。
273         //separatorも分割された状態で含まれる。
274         //"abcdefg".splitByArraySeparatorSeparated(["a", "e", "g"]);
275         //      = ["a", "bcd", "e", "f", "g"]
276         var retArray = new Array();
277         retArray[0] = this;
278         
279         for(var i = 0; i < separatorList.length; i++){
280                 var tmpArray = new Array();
281                 for(var k = 0; k < retArray.length; k++){
282                         var tmpArraySub = retArray[k].split(separatorList[i]);
283                         tmpArray[k] = new Array();
284                         for(var m = 0, mLen = tmpArraySub.length - 1; m < mLen; m++){
285                                 if(tmpArraySub[m] != ""){
286                                         tmpArray[k].push(tmpArraySub[m]);
287                                 }
288                                 tmpArray[k].push(separatorList[i]);
289                         }
290                         if(tmpArraySub[tmpArraySub.length - 1] != ""){
291                                 tmpArray[k].push(tmpArraySub[m]);
292                         }
293                 }
294                 retArray = new Array();
295                 retArray = retArray.concat.apply(retArray, tmpArray);
296         }
297         
298         if(retArray.length == 0){
299                 // https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split
300                 //文字列が空であるとき、split メソッドは、空の配列ではなく、1 つの空文字列を含む配列を返します。
301                 retArray.push("");
302         }
303         
304         return retArray;
305 }
306
307 String.prototype.splitByArraySeparatorSeparatedLong = function(separatorList){
308         //リスト中の文字列それぞれで分割された配列を返す。
309         //separatorも分割された状態で含まれる。
310         //separatorListの前の方にあるseparatorは、後方のseparatorによって分割されない。
311         //"abcdefgcdefg".splitByArraySeparatorSeparatedLong(["bcde", "cd", "f"]);
312         //      = ["a", "bcde", "f", "g", "cd", "e", "f", "g"]
313         //"for (i = 0; i != 15; i++) {".splitByArraySeparatorSeparatedLong(["!=", "(", ")", "="]);
314         //      = ["for ", "(", "i ", "=", " 0; i ", "!=", " 15; i++", ")", " {"]
315         var retArray = new Array();
316         var checkArray = new Array();
317         retArray[0] = this;
318         checkArray[0] = false;
319         
320         for(var i = 0; i < separatorList.length; i++){
321                 var tmpArray = new Array();
322                 var tmpCheckArray = new Array();
323                 for(var k = 0; k < retArray.length; k++){
324                         if(!checkArray[k]){
325                                 var tmpArraySub = retArray[k].split(separatorList[i]);
326                                 tmpArray[k] = new Array();
327                                 tmpCheckArray[k] = new Array();
328                                 for(var m = 0, mLen = tmpArraySub.length - 1; m < mLen; m++){
329                                         if(tmpArraySub[m] != ""){
330                                                 tmpArray[k].push(tmpArraySub[m]);
331                                                 tmpCheckArray[k].push(false);
332                                         }
333                                         tmpArray[k].push(separatorList[i]);
334                                         tmpCheckArray[k].push(true);
335                                 }
336                                 if(tmpArraySub[tmpArraySub.length - 1] != ""){
337                                         tmpArray[k].push(tmpArraySub[m]);
338                                         tmpCheckArray[k].push(false);
339                                 }
340                         } else{
341                                 tmpArray.push([retArray[k]]);
342                                 tmpCheckArray.push([true]);
343                         }
344                 }
345                 retArray = new Array();
346                 checkArray = new Array();
347                 retArray = retArray.concat.apply(retArray, tmpArray);
348                 checkArray = checkArray.concat.apply(checkArray, tmpCheckArray);
349         }
350         
351         if(retArray.length == 0){
352                 // https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split
353                 //文字列が空であるとき、split メソッドは、空の配列ではなく、1 つの空文字列を含む配列を返します。
354                 retArray.push("");
355         }
356         
357         return retArray;
358 }
359
360 String.prototype.trim = function(str){
361         return this.replace(/^[       ]+|[          ]+$/g, "").replace(/\n$/g, "");
362 }
363 //http://d.hatena.ne.jp/favril/20090514/1242280476
364 String.prototype.isKanjiAt = function(index){
365         var u = this.charCodeAt(index);
366         if( (0x4e00  <= u && u <= 0x9fcf) ||    // CJK統合漢字
367                 (0x3400  <= u && u <= 0x4dbf) ||        // CJK統合漢字拡張A
368                 (0x20000 <= u && u <= 0x2a6df) ||       // CJK統合漢字拡張B
369                 (0xf900  <= u && u <= 0xfadf) ||        // CJK互換漢字
370                 (0x2f800 <= u && u <= 0x2fa1f)){        // CJK互換漢字補助
371                 return true;
372         }
373     return false;
374 }
375 String.prototype.isHiraganaAt = function(index){
376         var u = this.charCodeAt(index);
377         if(0x3040 <= u && u <= 0x309f){
378                 return true;
379         }
380         return false;
381 }
382 String.prototype.isKatakanaAt = function(index){
383         var u = this.charCodeAt(index);
384         if(0x30a0 <= u && u <= 0x30ff){
385                 return true;
386         }
387         return false;
388 }
389 String.prototype.isHankakuKanaAt = function(index){
390         var u = this.charCodeAt(index);
391         if(0xff61 <= u && u <= 0xff9f){
392                 return true;
393         }
394         return false;
395 }