1 2 /** 3 * @name CeL data function 4 * @fileoverview 5 * 本檔案包含了 data 處理的 functions。 6 * @since 7 */ 8 9 10 if (typeof CeL === 'function') 11 CeL.setup_module('data', 12 { 13 require : 'data.native.to_fixed', 14 code : function(library_namespace, load_arguments) { 15 16 // requiring 17 var to_fixed; 18 eval(library_namespace.use_function(this)); 19 20 21 /** 22 * null module constructor 23 * @class data 處理的 functions 24 */ 25 CeL.data 26 = function() { 27 // null module constructor 28 }; 29 30 /** 31 * for JSDT: 有 prototype 才會將之當作 Class 32 */ 33 CeL.data 34 .prototype = { 35 }; 36 37 38 39 40 /* 41 eval(uneval(o)): IE 沒有 uneval 42 http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone 43 44 way1: 45 return YAHOO.lang.JSON.parse( YAHOO.lang.JSON.stringify( obj ) ); 46 47 TODO: 48 1. 49 防止交叉參照版: try 50 var a=function(){this.a=1,this.b={a:this.a},this.a={b:this.b};},b=cloneObject(a); 51 .or. 52 var a={},b; 53 a.a={a:1}; 54 a.b={a:a.a}; 55 a.a={b:a.b}; 56 b=cloneObject(a); 57 58 恐須改成 59 =new cloneObject(); 60 61 62 2. 63 equal() 64 65 */ 66 CeL.data 67 . 68 clone_object = 69 /** 70 * clone native Object 71 * @param {Object} object 72 * @param {Boolean} not_trivial 73 * @return 74 * @since 2008/7/19 11:13:10 75 */ 76 function clone_object(object, not_trivial) { 77 if (!object || !(object instanceof Object) 78 // || typeof(object) != 'object' 79 ) 80 return object; 81 var i, r = new object.constructor(object); // o.constructor() 82 for (i in object) 83 // o[i]===o: 預防 loop, 但還是不能防止交叉參照 84 r[i] = not_trivial/* ||o[i]===o */? object[i] : clone_object(object[i], deep); 85 return r; 86 }; 87 88 89 /* 2004/5/5 90 輸入('"','dh"fdgfg')得到2:指向"的位置 91 */ 92 function getQuoteIndex(quote,str){ // quote:['"/],[/]可能不太適用,除非將/[/]/→/[\/]/ 93 var i,l=0; 94 while(i=str.indexOf(quote,l),i>0&&str.charAt(i-1)=='\\') 95 if( str.slice(l,i-2).match(/(\\+)$/) && RegExp.$1.length%2 )break; 96 else l=i+1; 97 return i; 98 } 99 100 101 102 103 104 //{var a=[],b,t='',i;a[20]=4,a[12]=8,a[27]=4,a[29]=4,a[5]=6,a.e=60,a.d=17,a.c=1;alert(a);b=sortValue(a);alert(a+'\n'+b);for(i in b)t+='\n'+b[i]+' '+a[b[i]];alert(t);} 105 // 依值排出key array…起碼到現在,我還看不出此函數有啥大功用。 106 // array,否則會出現error! mode=1:相同value的以','合併,mode=2:相同value的以array填入 107 function sortValue(a,mode){ 108 var s=[],r=[],i,j,b,k=[]; 109 // 使用(i in n)的方法,僅有數字的i會自動排序;這樣雖不必用sort(),但數字亦會轉成字串。 110 for(i in a) 111 if((b=isNaN(i)?i:parseFloat(i)),typeof s[j=isNaN(j=a[i])?j:parseFloat(j)]=='undefined') 112 k.push(j),s[j]=b; 113 else if(typeof s[j]=='object')s[j].push(b); 114 else s[j]=[s[j],b]; 115 // sort 方法會在原地排序 Array 物件 116 for(i=0,k.sort(function(a,b){return a-b;});i<k.length;i++) 117 if(typeof(b=s[k[i]])=='object') 118 if(mode==1) 119 // b.join(',')與''+b效能相同 120 r.push(b.join(',')); 121 else if(mode==2)r.push(b); 122 else for(j in b)r.push(b[j]); 123 else r.push(b); 124 return r; 125 } 126 127 128 /* 2005/7/18 21:26 129 依照所要求的index(sortByIndex_I)對array排序。 130 sortByIndex_Datatype表某index為數字/字串或function 131 先設定sortByIndex_I,sortByIndex_Datatype再使用array.sort(sortByIndex); 132 133 example: 134 var array=[ 135 '123 avcf 334', 136 '131 hj 562', 137 '657 gfhj 435', 138 '131 ajy 52', 139 '345 fds 562', 140 '52 gh 435', 141 ]; 142 sortByIndex_I=[0,1],sortByIndex_Datatype={0:1,2:1}; 143 for(i in array)array[i]=array[i].split(' '); 144 array.sort(sortByIndex); 145 alert(array.join('\n')); 146 */ 147 var sortByIndex_I,sortByIndex_Datatype; 148 function sortByIndex(a,b){ 149 //alert(a+'\n'+b); 150 for(var i=0,n;i<sortByIndex_I.length;i++) 151 if(sortByIndex_Datatype[n=sortByIndex_I[i]]){ 152 if(typeof sortByIndex_Datatype[n]=='function'){ 153 if(n=sortByIndex_Datatype[n](a[n],b[n]))return n; 154 }else if(n=a[n]-b[n])return n; 155 }else if(a[n]!=b[n])return a[n]>b[n]?1:-1; 156 return 0; 157 } 158 159 /* 2005/7/18 21:26 160 依照所要求的index對array排序,傳回排序後的index array。 161 **假如設定了separator,array的元素會先被separator分割! 162 163 example: 164 var array=[ 165 '123 avcf 334', 166 '131 hj 562', 167 '657 gfhj 435', 168 '131 ajy 52', 169 '345 fds 562', 170 '52 gh 435', 171 ]; 172 alert(getIndexSortByIndex(array,' ',[0,1],[0,2])); 173 alert(array.join('\n')); // 已被separator分割! 174 175 */ 176 function getIndexSortByIndex(array, separator, indexArray, isNumberIndex) { 177 // 判定與事前準備(設定sortByIndex_I,sortByIndex_Datatype) 178 if (typeof indexArray === 'number') sortByIndex_I = [indexArray]; 179 else if (typeof indexArray !== 'object' || indexArray.constructor != Array) sortByIndex_I = [0]; 180 else sortByIndex_I = indexArray; 181 var i, sortByIndex_A = []; 182 sortByIndex_Datatype = {}; 183 if (typeof isNumberIndex == 'object') { 184 if (isNumberIndex.constructor == Array) { 185 sortByIndex_Datatype = {}; 186 for (i = 0; i < isNumberIndex.length; i++) sortByIndex_Datatype[isNumberIndex[i]] = 1; 187 } else sortByIndex_Datatype = isNumberIndex; 188 for (i in sortByIndex_Datatype) 189 if (isNaN(sortByIndex_Datatype[i]) || parseInt(sortByIndex_Datatype[i]) != sortByIndex_Datatype[i]) delete sortByIndex_Datatype[i]; 190 } 191 if (typeof array != 'object') return; 192 193 // main work: 可以不用重造array資料的話.. 194 for (i in array) { 195 if (separator) array[i] = array[i].split(separator); 196 sortByIndex_A.push(i); 197 } 198 sortByIndex_A.sort(function (a, b) { return sortByIndex(array[a], array[b]); }); 199 200 /* for: 重造array資料 201 var getIndexSortByIndexArray=array; 202 for(i in getIndexSortByIndexArray){ 203 if(separator)getIndexSortByIndexArray[i]=getIndexSortByIndexArray[i].split(separator); 204 sortByIndex_A.push(i); 205 } 206 sortByIndex_A.sort(function (a,b){return sortByIndex(getIndexSortByIndexArray[a],getIndexSortByIndexArray[b]);}); 207 */ 208 209 return sortByIndex_A; 210 } 211 212 213 //simpleWrite('char_frequency report3.txt',char_frequency(simpleRead('function.js')+simpleRead('accounts.js'))); 214 //{var t=reduceCode(simpleRead('function.js')+simpleRead('accounts.js'));simpleWrite('char_frequency source.js',t),simpleWrite('char_frequency report.txt',char_frequency(t));} // 所費時間:十數秒(…太扯了吧!) 215 CeL.data 216 . 217 /** 218 * 測出各字元的出現率。 普通使用字元@0-127:9-10,13,32-126,reduce後常用:9,32-95,97-125 219 * 220 * @param {String} text 221 * 文檔 222 * @return 223 * @memberOf CeL.data 224 */ 225 char_frequency=function (text) { 226 var i, a, c = [], d, t = '' + text, l = t.length, used = '', unused = '', u1 = -1, u2 = u1; 227 for (i = 0; i < l; i++) 228 if (c[a = t.charCodeAt(i)]) 229 c[a]++; 230 else 231 c[a] = 1; 232 for (i = u1; i < 256; i++) 233 if (c[i]) { 234 if (u2 + 1 === i) 235 used += ',' + i, unused += (u2 < 0 ? '' : '-' + u2); 236 u1 = i; 237 } else { 238 if (u1 + 1 === i) 239 unused += ',' + i, used += (u1 < 0 ? '' : '-' + u1); 240 u2 = i; 241 } 242 // 若是reduceCode()的程式,通常在120項左右。 243 for (i = 0, t = 'used:' + used.substr(1) + '\nunused:' + unused.substr(1) 244 + '\n', d = sortValue(c, 2).reverse(); i < d.length; i++) { 245 t += NewLine 246 + (a = d[i]) 247 + '[' 248 + fromCharCode(a).replace(/\0/g, '\\0').replace(/\r/g, '\\r') 249 .replace(/\n/g, '\\n').replace(/\t/g, '\\t') + ']' 250 + ': ' + (a = c[typeof a === 'object' ? a[0] : a]) + ' ' 251 + (100 * a / l); 252 //if(200*v<l)break; // .5%以上者←選購 253 } 254 alert(t); 255 return t; 256 }; 257 258 /* 259 flag: 260 (flag&1)==0 表情符號等不算一個字 261 (flag&1)==1 連表情符號等也算一個字 262 (flag&2)==1 將 HTML tag 全部消掉 263 264 可讀性/適讀性 265 http://en.wikipedia.org/wiki/Flesch-Kincaid_Readability_Test 266 http://en.wikipedia.org/wiki/Gunning_fog_index 267 Gunning-Fog Index:簡單的來說就是幾年的學校教育才看的懂你的文章,數字越低代表越容易閱讀,若是高於17那表示你的文章太難囉,需要研究生才看的懂,我是6.08,所以要受過6.08年的學校教育就看的懂囉。 268 Flesch Reading Ease:這個指數的分數越高,表示越容易了解,一般標準的文件大約介於60~70分之間。 269 Flesch-Kincaid grade level:和Gunning-Fog Index相似,分數越低可讀性越高,越容易使閱讀者了解,至於此指數和Gunning-Fog Index有何不同,網站上有列出計算的演算法,有興趣的人可以比較比較。 270 271 DO.normalize(): 合併所有child成一String, may crash IE6 Win! http://www.quirksmode.org/dom/tests/splittext.html 272 */ 273 CeL.data 274 . 275 /** 276 * 計算字數 count words. 277 * 278 * @param {String} text 279 * 文檔 280 * @param {Number} flag 文檔格式/處理方法 281 * @return {Number} 字數 282 * @memberOf CeL.data 283 */ 284 count_word = function(text, flag) { 285 var is_HTML = flag & 2; 286 287 // is HTML object 288 if (typeof text === 'object') 289 if (text.innerText) 290 text = text.innerText, is_HTML = 0; 291 else if (text.innerHTML) 292 text = text.innerHTML, is_HTML = 1; 293 294 if (typeof text !== 'string') 295 return 0; 296 297 // 和perl不同,JScript常抓不到(.*?)之後還接特定字串的東西,大概因為沒有s。(.*?)得改作((.|\n)*?)? 或者該加/img? 298 if (is_HTML) 299 text = text 300 .replace(/<!--((.|\n)*?)-->/g, '') 301 .replace(/<[\s\n]*\/?[\s\n]*[a-z][^<>]*>/gi, ''); 302 303 if (flag & 1) 304 // 連表情符號或 '(~。),' / 破折號 '——' / 刪節號 '……' 等標點符號也算一個字 305 text = text.replace(/[\+\-–*\\\/?!,;.<>{}\[\]@#$%^&_|"'~`—…、,;。!?:()()「」『』“”‘’]{2,}/g, ';'); 306 307 return text 308 // 去掉注解用的括弧、書名號、專名號、印刷符號等 309 .replace(/[()()《》〈〉*#]+/g, '') 310 // 將英文、數字等改成單一字母。[.]: 縮寫 311 // http://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF 312 .replace(/[a-zA-ZÀ-ÖØ-öø-ʨ\-–'.\d]{2,}/g, 'w') 313 // date/time or number 314 .replace(/[\d:+\-–\.\/,]{2,}/g, '0') 315 // 再去掉*全部*空白 316 .replace(/[\s\n ]+/g, '') 317 .length; 318 }; 319 320 321 322 323 324 325 326 CeL.data 327 . 328 /** 329 * 運算式值的二進位表示法 已最佳化:5.82s/100000次dec_to_bin(20,8)@300(?)MHz,2.63s/100000次dec_to_bin(20)@300(?)MHz 330 * @param {Number} number number 331 * @param places places,字元數,使用前置0來填補回覆值 332 * @return 333 * @example 334 * {var d=new Date,i,b;for(i=0;i<100000;i++)b=dec_to_bin(20);alert(gDate(new Date-d));} 335 * @memberOf CeL.data 336 */ 337 dec_to_bin = function(number, places) { 338 if (places && number + 1 < (1 << places)) { 339 var h = '', b = number.toString(2), i = b.length; 340 for (; i < places; i++) 341 h += '0'; 342 return h + b; 343 } 344 // native code 還是最快! 345 return number.toString(2); 346 347 // 上兩代:慢 var b='',c=1;for(p=p&&n<(p=1<<p)?p:n+1;c<p;c<<=1)b=(c&n?'1':'0')+b;return b; // 不用'1:0',型別轉換比較慢.不用i,多一個變數會慢很多 348 // 上一代:慢 if(p&&n+1<(1<<p)){var h='',c=1,b=n.toString(2);while(c<=n)c<<=1;while(c<p)c<<=1,h+='0';return h+(n?n.toString(2):'');} 349 }; 350 351 352 353 354 355 /* 356 value (Array)=value,(Object)value= 357 [null]=value 累加=value 358 value=[null] value='' 359 360 type: value type ['=','][int|float|_num_] 361 *前段 362 以[']或["]作分隔重定義指定號[=]與分隔號[,] 363 *後段 364 數字表累加 365 'int'表整數int,累加1 366 'float'表示浮點數float,累加.1 bug:應該用.to_fixed() 367 不輸入或非數字表示string 368 369 mode 370 _.set_obj_value.F.object 371 _.set_obj_value.F.array(10進位/當做數字) 372 number: key部分之base(10進位,16進位等) 373 374 example: 375 set_obj_value('UTCDay','Sun,Mon,Tue,Wed,Thu,Fri,Sat','int'); // 自動從0開始設,UTCDay.Tue=2 376 set_obj_value('UTCDay','Sun,Mon,Tue,Wed,Thu,Fri,Sat'); // UTCDay.Sun=UTCDay.Fri='' 377 set_obj_value('add','a=3,b,c,d',2); // 累加2。add.b=5 378 set_obj_value('add','a,b,c,d',1,_.set_obj_value.F.array); // add[2]='c' 379 set_obj_value('add','4=a,b,c,d',2,_.set_obj_value.F.array); // 累加2。add[8]='c' 380 381 */ 382 CeL.data 383 . 384 /** 385 * 設定object之值,輸入item=[value][,item=[value]..]。 386 * value未設定會自動累加。 387 * 使用前不必需先宣告…起碼在現在的JS版本中 388 * @param obj object name that need to operate at 389 * @param value valueto set 390 * @param type 累加 / value type 391 * @param mode mode / value type 392 * @return 393 * @memberOf CeL.data 394 */ 395 set_obj_value = function(obj, value, type, mode) { 396 if (!value || typeof o !== 'string') 397 return 1; 398 399 var a, b, i = 0, p = '=', sp = ',', e = "if(typeof " + obj + "!='object')" 400 + obj + "=new " + (mode ? 401 // "[]":"{}" 402 // Array之另一種表示法:[value1,value2,..], Object之另一種表示法:{key1:value1,key2:value2,..} 403 "Array" : "Object") 404 + ";", 405 // l: item, n: value to 累加 406 n, Tint = false, cmC = '\\u002c', eqC = '\\u003d'; 407 if (type) { 408 if (typeof a === 'string') { 409 a = type.charAt(0); 410 if (a === '"' || a === "'") { 411 a = type.split(a); 412 p = a[1], sp = a[2], type = a[3]; 413 } 414 } 415 if (type === 'int') 416 type = 1, Tint = true; 417 else if (type === 'float') 418 type = .1; 419 else if (isNaN(type)) 420 type = 0; 421 else if (type == parseInt(type)) 422 type = parseInt(type), Tint = true; 423 else 424 type = parseFloat(type); // t被設成累加數 425 } 426 //else t=1; 427 428 if (typeof value === 'string') 429 value = value.split(sp); 430 // escape regex characters from jQuery 431 cmC = new RegExp(cmC.replace( 432 /([\.\\\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"), 'g'), 433 eqC = new RegExp(eqC.replace( 434 /([\.\\\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"), 'g'); 435 436 if (type) 437 // n: 現在count到.. 438 n = -type; 439 440 for (; i < value.length; i++) { 441 if (value[i].indexOf(p) === -1) 442 value[i] = mode ? p + value[i] : value[i] + p;// if(v[i].indexOf(p)==-1&&m)v[i]=p+v[i];// 443 if (mode && value[i] === p) { 444 n += type; 445 continue; 446 } 447 a = value[i].split(p); 448 if (!mode && !a[0]) 449 // 去掉不合理的(Array可能有NaN index,所以不設條件。) 450 continue; 451 a[0] = a[0].replace(cmC, ',').replace(eqC, '='), a[1] = a[1].replace( 452 cmC, ',').replace(eqC, '='); 453 if (type) 454 if (mode) { 455 if (!a[0]) 456 a[0] = (n += type); 457 else if (!isNaN(b = mode > 0 ? parseInt(a[0], mode) : a[0])) 458 n = Tint ? (a[0] = parseInt(b)) : parseFloat(b); 459 } else if (!a[1]) 460 a[1] = (n += type); 461 else if (!isNaN(a[1])) 462 n = Tint ? parseInt(a[1]) : parseFloat(a[1]); 463 if (!type || Tint && isNaN(b = parseInt(a[1])) 464 || isNaN(b = parseFloat(a[1]))) 465 b = a[1]; 466 a = a[0]; 467 e += obj + '[' + (!type || isNaN(a) ? dQuote(a) : a) + ']=' 468 + (!type || isNaN(b) ? dQuote(b) : b) + ';'; 469 } 470 471 try { 472 //if(o=='kk')alert(e.slice(0,500)); 473 // 因為沒想到其他方法可存取Global的object,只好使用eval..可以試試obj=set_obj_value(0,..){this=new Aaaray/Object} 474 library_namespace.eval_code(e); 475 } catch (e) { 476 library_namespace.err('Error @ ' + obj); 477 library_namespace.err(e); 478 return 2; 479 } 480 }; 481 482 _.set_obj_value.F = { 483 // object is default 484 'object' : 0, 485 'array' : -1 486 }; 487 488 489 490 CeL.data 491 . 492 /** 493 * 將字串組分作 Object 494 * @param {String} value_set 字串組, e.g., 'a=12,b=34' 495 * @param assignment_char char to assign values, e.g., '=' 496 * @param end_char end char of assignment 497 * @return 498 * @since 2006/9/6 20:55, 2010/4/12 23:06:04 499 * @memberOf CeL.data 500 */ 501 split_String_to_Object = function(value_set, assignment_char, end_char) { 502 if (typeof value_set !== 'string' || !value_set) 503 return {}; 504 505 value_set = value_set.split(end_char || /[,;]/); 506 507 if (!assignment_char) 508 assignment_char = /[=:]/; 509 510 var a, o = {}, _e = 0, l = value_set.length; 511 for (; _e < l; _e++) { 512 // http://msdn.microsoft.com/library/en-us/jscript7/html/jsmthsplit.asp 513 a = value_set[_e].split(assignment_char, 2); 514 //library_namespace.debug(value_set[_e] + '\n' + a[0] + ' ' + a[1], 2); 515 if (a[0] !== '') 516 o[a[0]] = a[1]; 517 } 518 return o; 519 }; 520 521 522 523 524 525 526 /* 2003/10/1 15:46 527 比較string:m,n從起頭開始相同字元數 528 return null: 格式錯誤,-1: !m||!n 529 若一開始就不同:0 530 531 532 TODO: 533 534 test starting with 535 536 2009/2/7 7:51:58 537 看來測試 string 的包含,以 .indexOf() 最快。 538 即使是比較 s.length 為極小常數的情況亦復如此 539 540 下面是快到慢: 541 542 // long,short 543 var contain_substring=[ 544 function(l,s){ 545 var a=0==l.indexOf(s); 546 return a; 547 } 548 ,function(l,s){ 549 return 0==l.indexOf(s); 550 } 551 ,function(l,s){ 552 return s==l.slice(0,s.length); 553 } 554 ,function(l,s){ 555 return l.match(s); 556 } 557 ,function(l,s){ 558 for(var i=0;i<s.length;i++) 559 if(s.charAt(i)!=l.charAt(i))return 0; 560 return 1; 561 } 562 ]; 563 564 function test_contain_substring(){ 565 for(var i=0;i<contain_substring.length;i++){ 566 var t=new Date; 567 for(var j=0;j<50000;j++){ 568 contain_substring[i]('sdfgjk;sh*dn\\fj;kgsamnd nwgu!eoh;nfgsj;g','sdfgjk;sh*dn\\fj;kgsamnd nwgu!'); 569 contain_substring[i]('sdbf6a89* /23hsauru','sdbf6a89* /23'); 570 } 571 sl(i+': '+(new Date-t)); 572 } 573 } 574 575 576 // 極小常數的情況: 577 // long,short 578 var contain_substring=[ 579 function(l,s){ 580 var a=0==l.indexOf(s); 581 return a; 582 } 583 ,function(l,s){ 584 return 0==l.indexOf(s); 585 } 586 ,function(l,s){ 587 return s==l.slice(0,1); 588 } 589 ,function(l,s){ 590 return s.charAt(0)==l.charAt(0); 591 } 592 ,function(l,s){ 593 return l.match(/^\//); 594 } 595 ]; 596 597 function test_contain_substring(){ 598 for(var i=0;i<contain_substring.length;i++){ 599 var t=new Date; 600 for(var j=0;j<50000;j++){ 601 contain_substring[i]('a:\\sdfg.dfg\\dsfg\\dsfg','/'); 602 contain_substring[i]('/dsfg/adfg/sadfsdf','/'); 603 } 604 sl(i+': '+(new Date-t)); 605 } 606 } 607 608 609 */ 610 611 CeL.data 612 . 613 /** 614 * test if 2 string is at the same length 615 * @param s1 string 1 616 * @param s2 string 2 617 * @return 618 * @memberOf CeL.data 619 */ 620 same_length=function(s1, s2) { 621 if (typeof m !== 'string' || typeof n !== 'string') 622 return; 623 if (!s1 || !s2) 624 return 0; 625 626 var i = s1.length, b = 0, s = s2.length; 627 if (i < s) { 628 if ( 629 //m==n.slice(0,i=m.length) 630 0 === s2.indexOf(s1)) 631 return i; 632 } else if ( 633 //s2==s1.slice(0,i=s2.length) 634 i = s, 0 === s1.indexOf(s2)) 635 return i; 636 637 //sl('*same_length: start length: '+i); 638 while ((i = (i + 1) >> 1) > 1 && (s = s2.substr(b, i))) 639 //{sl('same_length: '+i+','+b+'; ['+m.substr(b)+'], ['+s+'] of ['+n+']'); 640 if (s1.indexOf(s, b) === b) 641 b += i; 642 //sl('*same_length: '+i+','+b+'; ['+m.charAt(b)+'], ['+n.charAt(b)+'] of ['+n+']'); 643 //var s_l=i&&m.charAt(b)==n.charAt(b)?b+1:b; 644 //sl('*same_length: '+s_l+':'+m.slice(0,s_l)+',<em>'+m.slice(s_l)+'</em>; '+n.slice(0,s_l)+',<em>'+n.slice(s_l)+'</em>'); 645 return i && s1.charAt(b) === s2.charAt(b) ? b + 1 : b; 646 }; 647 648 649 650 //----------------------------------------------------------------------------- 651 652 653 654 /* 655 http://www.bipm.org/en/si/si_brochure/chapter3/prefixes.html 656 http://en.wikipedia.org/wiki/International_System_of_Units 657 http://www.merlyn.demon.co.uk/js-maths.htm#RComma 658 http://physics.nist.gov/cuu/Units/prefixes.html 659 http://www.uni-bonn.de/~manfear/numbers_names.php 660 http://wawa.club.hinet.net/cboard1/HCB_Dis.asp?BrdNo=78&SubNo=78761&Club=0&ClsName=%B1%D0%A8%7C%BE%C7%B2%DF 661 http://bbs.thu.edu.tw/cgi-bin/bbscon?board=English&file=M.1046073664.A&num=106 662 */ 663 //to_SI_prefix[generateCode.dLK]='setTool,to_fixed,-to_SI_prefix.n,-to_SI_prefix.v'; 664 665 666 CeL.data 667 . 668 /** 669 * 將數字轉為 K, M, G 等 SI prefixes 表示方式,例如 6458 轉成 6.31K。 670 * @param {Number} number 數字 671 * @param {Number} digits to fixed digit 672 * @type {String} 673 * @return {String} SI prefixes 表示方式 674 * @requires setTool,to_fixed 675 * @memberOf CeL.data 676 */ 677 to_SI_prefix = function (number, digits) { 678 function to_SI_prefix(number, digits) { 679 var p = 1, v = to_SI_prefix.v; 680 if (number < v[0]) 681 return number; 682 683 while (number >= v[p]) 684 p++; 685 686 return to_fixed.call(number / v[--p], isNaN(digits) ? 2 : digits) 687 + to_SI_prefix.s[p]; 688 } 689 690 // Initialization 691 // 在 IE5 中,因為 base 沒有預先定義,因此在這邊會出現錯誤。 692 var _s = _.to_SI_prefix, base = _s.base, 693 N = base, v = to_SI_prefix.v = [ base ], 694 l = (to_SI_prefix.s = _s.symbol.split(',')).length; 695 while (l--) 696 v.push(N *= base); 697 698 return library_namespace.replace_function(_, 'to_SI_prefix', to_SI_prefix); 699 }; 700 701 // define what is "1k" 702 _.to_SI_prefix.base = 1024; 703 _.to_SI_prefix.symbol = 'k,M,G,T,P,E,Z,Y'; 704 705 706 // 將漢字轉為阿拉伯數字表示法(0-99999) 707 function turnKanjiToNumbers(num) { 708 if (!num) return 0; 709 if (!isNaN(num)) return num; 710 var i = 0, l, m, n = '〇,一,二,三,四,五,六,七,八,九'.split(','), d = '萬,千,百,十,'.split(','), r = 0 711 // O, ○=[〇] http://zh.wikipedia.org/wiki/%E6%97%A5%E8%AA%9E%E6%95%B8%E5%AD%97 712 , p = ('' + num).replace(/\s/g, '').replace(/[O○]/g, '〇') 713 ; 714 for (; i < n.length; i++) n[n[i]] = i; 715 for (i = 0; i < d.length; i++) { 716 if (p && (m = d[i] ? p.indexOf(d[i]) : p.length) != -1) 717 if (!m && d[i] === '十') r += 1, p = p.slice(1); else if (isNaN(l = n[p.slice(0, m).replace(/^〇+/, '')])) return num; else r += l, p = p.slice(m + 1); 718 if (d[i]) r *= 10; 719 } 720 return r; 721 } 722 //alert(turnKanjiToNumbers('四萬〇三百七十九')); 723 //alert(turnKanjiToNumbers('十')); 724 725 // 將阿拉伯數字轉為中文數字大、小兩種表示法/讀法 ,to_Chinese_numeralD,to_Chinese_numeralInit,"to_Chinese_numeralInit();",_to_Chinese_numeral,to_Chinese_numeral 726 var to_Chinese_numeralD; 727 //to_Chinese_numeralInit[generateCode.dLK]='to_Chinese_numeralD'; 728 function to_Chinese_numeralInit(){ 729 to_Chinese_numeralD={ 730 'num':['〇,一,二,三,四,五,六,七,八,九'.split(','),'零,壹,貳,參,肆,伍,陸,柒,捌,玖'.split(',')] // 數字 叄 731 // http://zh.wikipedia.org/wiki/%E4%B8%AD%E6%96%87%E6%95%B0%E5%AD%97 http://zh.wikipedia.org/wiki/%E5%8D%81%E8%BF%9B%E5%88%B6 http://zh.wikipedia.org/wiki/%E4%B8%AD%E6%96%87%E6%95%B0%E5%AD%97 http://lists.w3.org/Archives/Public/www-style/2003Apr/0063.html http://forum.moztw.org/viewtopic.php?t=3043 http://www.moroo.com/uzokusou/misc/suumei/suumei.html http://espero.51.net/qishng/zhao.htm http://www.nchu.edu.tw/~material/nano/newsbook1.htm 732 // 十億(吉),兆(萬億),千兆(拍),百京(艾),十垓(澤),秭(堯),秭:禾予;溝(土旁);,無量大數→,無量,大數;[載]之後的[極]有的用[報] 異體:阿僧[禾氏],For Korean:阿僧祗;秭:禾予,抒,杼,For Korean:枾 For Korean:不可思議(不:U+4E0D→U+F967) 733 // Espana應該是梵文所譯 因為根據「大方廣佛華嚴經卷第四十五卷」中在「無量」這個數位以後還有無邊、無等、不可數、不可稱、不可思、不可量、不可說、不可說不可說,Espana應該是指上面其中一個..因為如果你有心查查Espana其實應該是解作西班牙文的「西班牙」 734 ,'d':',萬,億,兆,京,垓,秭,穰,溝,澗,正,載,極,恒河沙,阿僧祇,那由他,不可思議,無量,大數,Espana' // denomination, 單位 735 // http://zh.wikipedia.org/wiki/%E5%8D%81%E9%80%80%E4%BD%8D 736 // 比漠微細的,是自天竺的佛經上的數字。而這些「佛經數字」已成為「古代用法」了。 737 // 小數單位(十退位):分,釐(厘),毫(毛),絲,忽,微,纖,沙,塵(納),埃,渺,漠(皮),模糊,逡巡,須臾(飛),瞬息,彈指,剎那(阿),六德(德),虛,空,清,淨 or:,虛,空,清,淨→,空虛,清淨(仄),阿賴耶,阿摩羅,涅槃寂靜(攸) 738 ,'bd':0 // 暫時定義 739 }; 740 with(to_Chinese_numeralD) 741 bd=[(',十,百,千'+to_Chinese_numeralD.d).split(','),(',拾,佰,仟'+to_Chinese_numeralD.d).split(',')] // base denomination 742 ,d=d.split(','); 743 } 744 to_Chinese_numeralInit(); 745 /* 處理1-99999的數,尚有bug 746 東漢時期的《數述記遺》 747 一是上法,為自乘系統: 萬萬為億,億億為兆,兆兆為京。 748 二是中法,為萬進系統,皆以萬遞進 749 三是下法,為十進系統,皆以十遞進←現代的科學技術上用的“兆”,以及_to_Chinese_numeral()用的 750 */ 751 //_to_Chinese_numeral[generateCode.dLK]='to_Chinese_numeralD,*to_Chinese_numeralInit();'; 752 function _to_Chinese_numeral(numStr, kind) { 753 if (!kind) 754 kind = 0; 755 // 用r=[]約多花一倍時間! 756 var i = 0, r = '', l = numStr.length - 1, d, tnum = to_Chinese_numeralD.num[kind], tbd = to_Chinese_numeralD.bd[kind], zero = tnum[0]; 757 for (; i <= l; i++) 758 // if(d=parseInt(numStr.charAt(i)))比較慢 759 if ((d = numStr.charAt(i)) != '0') 760 // '〇一二三四五六七八'.charAt(d) 比較慢 761 r += tnum[d] + tbd[l - i]; 762 else if (r.slice(-1) != zero) 763 if (Math.floor(numStr.substr(i + 1))) 764 r += zero; 765 else 766 break; 767 return r; 768 } 769 //2.016,2.297,2.016 770 //{var d=new Date,v='12345236',i=0,a;for(;i<10000;i++)a=to_Chinese_numeral(v);alert(v+'\n→'+a+'\ntime:'+gDate(new Date-d));} 771 772 //to_Chinese_numeral[generateCode.dLK]='to_Chinese_numeralD,to_Chinese_numeralInit,_to_Chinese_numeral,to_Chinese_numeral';//,*to_Chinese_numeralInit(); 773 /** 774 * 將數字轉為漢字表示法。 775 * num>1京時僅會取概數,此時得轉成string再輸入! 776 * TODO: 777 * 統整:尚有bug。 778 * 廿卅 779 * @param num 780 * @param kind 781 * @returns 782 */ 783 function to_Chinese_numeral(num, kind) { 784 // num=parseFloat(num); 785 if (typeof num == 'number') 786 num = num.toString(10); 787 num = ('' + num).replace(/[,\s]/g, ''); 788 if (isNaN(num)) 789 return '(非數值)'; 790 if (num.match(/(-?[\d.]+)/)) 791 num = RegExp.$1; 792 if (!kind) 793 kind = 0; 794 795 var j, i, d = num.indexOf('.'), k, l, m, addZero = false, tnum = to_Chinese_numeralD.num[kind], zero = tnum[0], td = to_Chinese_numeralD.d;// i:integer,整數;d:decimal,小數 796 if (d == -1) 797 d = 0; 798 else 799 for (num = num.replace(/0+$/, ''), i = num.substr(d + 1), num = num 800 .slice(0, d), d = '', j = 0; j < i.length; j++) 801 // 小數 802 d += tnum[i.charAt(j)]; 803 804 // 至此num為整數 805 if (num.charAt(0) == '-') 806 i = '負', num = num.substr(1); 807 else 808 i = ''; 809 num = num.replace(/^0+/, ''); 810 811 m = num.length % 4, j = m - 4, l = (num.length - (m || 4)) / 4; 812 // addZero=false, l=Math.floor((num.length-1)/4) 813 for (; j < num.length; m = 0, l--) 814 // 這邊得用 parseInt( ,10): parseInt('0~')會用八進位,其他也有奇怪的效果。 815 if (Math.floor(m = m ? num.slice(0, m) : num.substr(j += 4, 4))) { 816 m = _to_Chinese_numeral(m, kind); 817 if (addZero = addZero && m.charAt(0) != zero) 818 i += zero + m + td[l], addZero = false; 819 else 820 i += m + td[l]; 821 } else 822 addZero = true; 823 824 return (i ? i.slice(0, 2) == '一十' ? i.substr(1) : i : zero) 825 + (d ? '點' + d : ''); 826 } 827 828 // 轉換成金錢表示法 829 //turnToMoney[generateCode.dLK]='to_Chinese_numeral'; 830 function turnToMoney(num){ 831 var i=(num=to_Chinese_numeral(num,1)).indexOf('點'); 832 return i==-1?num+'圓整':num.slice(0,i)+'圓'+num.charAt(++i)+'角'+(++i==num.length?'':num.charAt(i++)+'分')+num.substr(i); 833 } 834 835 836 // 分斷行 2003/1/25 22:40 837 function getText() {//html→text 838 //<.+?> <[^>]+> <\s*\/?\s*[a-zA-Z](.*?)> <! 過慢? 839 return this.valueOf().replace(/<s>[^<]*<\/s>/gi, '').replace(/<w?br[^>]*>/gi, '\n').replace(/<\/?[A-Za-z][^>]*>/g, ''); 840 } 841 function trimStr_(s, l, m) { 842 var lt,lt2,gt,i=0,c=l,t='',I=0;//less than,great than,index,left count index(left length now),text now,text index 843 while(I<s.length){ 844 //將lt,gt定在下一label之首尾,i為下一次搜尋起點.label定義:/<.+?>/ 845 if(i!=-1)if((lt=s.indexOf('<',i))!=-1){ 846 if((gt=s.indexOf('>',lt+1))==-1)i=lt=-1; 847 else{i=gt+1;while(lt!=-1&&(lt2=s.indexOf('<',lt+1))!=-1&<2<gt)lt=lt2;} 848 }else i=lt=-1; 849 //if(s.indexOf('')!=-1)alert(i+','+lt+','+gt+';'+l+','+c+'\n'+t); 850 if(lt==-1)gt=lt=s.length; 851 //未來:考慮中英文大小,不分隔英文字。前提:'A'<'z'..或許不用 852 while(I+c<=lt){t+=s.substr(I,c)+(m?'\n':'<br/>');I+=c;c=l;} 853 t+=s.slice(I,gt+1);c-=lt-I;I=gt+1; 854 } 855 return t; 856 } 857 /* 將字串以長l分隔 858 m==0: html用, 1:text 859 */ 860 //trimStr[generateCode.dLK]='trimStr_'; 861 function trimStr(l,m){ 862 var s=this.valueOf(),t=[],sp='<br/>'; 863 if(!s||!l||l<1||!String.fromCharCode)return m?s.gText():s;//||!String.charCodeAt:v5.5 864 s=s.turnU(m);//(m):這樣就不用再費心思了.不過既然都作好了,就留著吧..不,還是需要 865 if(s.length<=l)return s; 866 if(!m)s=s.replace(/<w?br([^>]*)>/gi,sp); 867 868 s=s.split(sp=m?'\n':sp);//deal with line 869 try{ 870 // 預防JS5不能push 871 for(var i=0;i<s.length;i++)t.push(trimStr_(s[i],l,m)); 872 }catch(e){return this.valueOf();} 873 return t.join(sp); 874 } 875 876 877 878 879 880 //----------------------------------------------------------------------------- 881 882 883 //mode=1:不取空字串 884 // .split() appears from Internet Explorer 4.0 885 // <a href="http://msdn.microsoft.com/en-us/library/s4esdbwz%28v=VS.85%29.aspx" accessdate="2010/4/16 20:4">Version Information (Windows Scripting - JScript)</a> 886 function strToArray(s, mode) { 887 var a = [], last = 0, i; 888 while ((i = s.indexOf(sp, last)) != -1) { 889 if (mode == 0 || last != i) a[a.length] = s.slice(last, i); 890 last = i + 1; 891 } 892 if (mode == 0 || last != s.length) a[a.length] = s.slice(last); 893 return a; 894 } 895 896 //去除s之空白,包括字與字之間的 897 function disposeSpace(s) { 898 if (!s) return s; 899 var r = "", i, last; 900 while ((i = s.indexOf(' ', last)) != -1) 901 r += s.slice(last, i), last = i + 1; 902 r += s.slice(last); 903 return r; 904 } 905 906 //以label,mode:m置換s,先找到先贏 907 //輸入t['$k']=..會有問題,需用t['\\$k']=.. 908 function changeV(s, l, m) { 909 var i, r, re, t; //var I=''; 910 if (!m) m = 'g'; 911 if (s && (t = l ? l : label)) for (i in t) { 912 //I+=', '+i+'='+t[i]; 913 re = new RegExp(i, m); 914 s = s.replace(re, t[i]); //r=s.replace(re,t[i]);s=r; 915 } 916 //pLog(I.substr(2)); 917 //pLog('changeV:'+s); 918 return s; 919 } 920 921 /* 922 //以label置換s,先找到先贏 923 function changeV(s) { 924 for (var i, j = 0; j < labelN.length; j++) 925 if ((i = s.indexOf(labelN[j])) != -1) 926 s = s.slice(0, i) + labelV[j] + s.slice(i + labelN[j].length) 927 , j = 0; //research from begin 928 return s; 929 } 930 */ 931 932 933 934 //TODO: Object.keys(obj) 935 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys 936 CeL.data 937 . 938 get_Object_key = function(o) { 939 if (_.is_Array(o)) 940 return o; 941 //if (!_.is_Object(o)) return; 942 var i, l = []; 943 for(i in o) 944 l.push(i); 945 return l; 946 }; 947 948 CeL.data 949 . 950 get_Object_value = function(o) { 951 if (_.is_Array(o)) 952 return o; 953 //if (!_.is_Object(o)) return; 954 var i, l = []; 955 for(i in o) 956 l.push(o[i]); 957 return l; 958 }; 959 960 961 962 963 964 return ( 965 CeL.data 966 ); 967 } 968 969 970 }); 971 972