2008-04-15
zt:基于javascript的拼音字典及应用举例
不论是浏览器还是操作系统,对中文的支持已经有了长足的进步,但是在一些细节方面仍然存在不足。比如,在windows文件浏览时,我们可以通过按下文件夹名的首字母来快速定位文件夹,但是对于文件夹名为中文的文件夹却无能为力。类似的,在网页浏览中,也存在类似问题。这种问题不会妨碍使用,但却伤害体验。本文分两部分,第一部分简单介绍基于javascript的拼音字典的构造方法;第二部分简单介绍几个应用。
创建基于javascript的拼音字典
之所以基于javascript,是为了获取较高的相应速度,同时减少服务端的压力。我在字典设计时有两个目标:一是查询速度要足够快;二是字典要尽量小。怎么样足够快?数组;怎样尽量小?压缩!好,让我们开始设计吧:
- 字典准备
找一个汉字拼音对照表,用正则表达式将这些汉字与拼音关联起来创建对象字典(为了简单,忽略了多音字)。
结果类似于 a["爱"]='ai',a['我']='wo'…… - 转换为数组
利用汉字具有唯一ascii码值这一特点,将汉字与拼音的对应关系转换为ascii与拼音的对应关系。javascript求中文的ascii码的函数是charCodeAt()。比如'爱'的ascii码是29233,'我'的ascii码是25105……则可以将对象字典转换为数组字典:a[29233]='ai',a[25105]='wo'……
数组字典就完成了。转换以后,要查找爱的拼音,可以这样:a['爱'.charCodeAt()],方便快捷吧? - 压缩数组字典
我使用了三个压缩来压缩字典。
第一个压缩是减小数组空间。因为汉字的ascii值往往比较大,最小的也将近20000。所以我们可以将数组的索引往前平移,我采用的值是18000,为了确保安全,我留出了一定盈余空间。
平移后的数组字典为:a[29233-18000]='ai',a[25205-18000]='wo'……
第二个压缩是减少数据的重复。在字典的近7000个汉字中,读音的种类是较少的。将所有读音种类存到数组b内,然后在数组字典a内记录读音在b中的索引即可。
比如'ai'在b中的索引为1,则数组字典变为 a[11233]=1……
这个时候要查找'爱'的拼音,可以这样 b[a['爱'.charCodeAt()-18000]]
第三个压缩时gzip压缩,这个以后单独在另外的文章中探讨。
经过这几步,简单的字典基本设计好了:字典下载(13k)。这个文件,如果用浏览器直接下载保存,是未Gzip压缩版,约40k。压缩版需要用下载工具下载,约13k。
字典应用举例
我已经将几个应用整理到一个页面中,您可以直接观看效果演示。
评论
KKFC
2008-04-15
Why not localeCompare()?
该方法目前已作为ECMAScript v3标准,在支持JavaScript 1.5(Mozilla、Netscape 6+)以及JScript 5.5(IE 5.5+)的浏览器中均得到了支持。
引用
JavaScript提供了一种更简便的方法用于比较两个字符串——localeCompare(),localeCompare()使用本地特定的顺序来比较两个字符串,语法如下:
string.localeCompare(target)
参数target是要与string进行比较的字符串。
如果string小于target,则localeCompare()返回小于0的数;
如果string大于target,返回大于0的数;
如果相等(或按照本地顺序的约定两者顺序相当),则返回0。
利用该方法替换上面冗长的作法后,除了代码减少了之外,运行速度也快了不少,而且还支持其它字符库的本地排序。
修改后代码如下:
string.localeCompare(target)
参数target是要与string进行比较的字符串。
如果string小于target,则localeCompare()返回小于0的数;
如果string大于target,返回大于0的数;
如果相等(或按照本地顺序的约定两者顺序相当),则返回0。
利用该方法替换上面冗长的作法后,除了代码减少了之外,运行速度也快了不少,而且还支持其它字符库的本地排序。
修改后代码如下:
<script type="text/javascript">
<!--
function startSort(){
var a=document.getElementById('s').value;
a=a.split(',')
a.sort();
document.getElementById('r1').value=a;
a.sort(function(a,b){return a.localeCompare(b)});
document.getElementById('r2').value=a;
}
//-->
</script>
</head>
<body>
<p>包含汉字的字符串数组(用逗号","隔开):<br />
<textarea id="s" style="width: 100%; overflow: scroll; word-wrap: normal;" rows="10">张韶涵,b土,abort,张学友,something,苹果,五月天,刘德华,香蕉,apple,范玮琪,阿桑</textarea></p>
<p style="text-align: center"><input type="button" value="排序测试" onclick="startSort()" style="width: 300px" /></p>
<p>默认排序结果:<br />
<textarea id="r1" style="width: 100%; overflow: scroll; word-wrap: normal;" rows="10"></textarea></p>
<p>汉字拼音顺序排序结果:<br />
<textarea id="r2" style="width: 100%; overflow: scroll; word-wrap: normal;" rows="10"></textarea></p>
</body>
</html>
该方法目前已作为ECMAScript v3标准,在支持JavaScript 1.5(Mozilla、Netscape 6+)以及JScript 5.5(IE 5.5+)的浏览器中均得到了支持。
jindw
2008-04-15
这段代码中那个大数组在写法上还是有一定的压缩空间的。
提一个优化建议:
例:
javascript:new Array(10).concat([12,34,56]).concat("asdasdad,as,da,sdasdad,asda,sd".split(','))
那个大数组可以通过例子中用到的一些技巧,进一步压缩。
提一个优化建议:
例:
javascript:new Array(10).concat([12,34,56]).concat("asdasdad,as,da,sdasdad,asda,sd".split(','))
那个大数组可以通过例子中用到的一些技巧,进一步压缩。
hama
2008-04-15
HexUzHoNG 写道
NB!
应用三:关键词筛选
好像不可以连续输入首字母拼音筛选?
比如我输:h
输出:河北省 黑龙江省 河南省 湖北省 湖南省 海南省
接着输:hb
没有显示“河北省”,就提示没有匹配项了?
应用三:关键词筛选
好像不可以连续输入首字母拼音筛选?
比如我输:h
输出:河北省 黑龙江省 河南省 湖北省 湖南省 海南省
接着输:hb
没有显示“河北省”,就提示没有匹配项了?
这个是全拼音匹配,不是匹配首字母,你可以居于自己的需求重写一下,就好了
hama
2008-04-15
查询速度还算快
而且比较全,碰到多音字可能会有点问题,据项目具体情况而定,如果多音字很重要的话可以找个多音字字典结合使用一下
而且比较全,碰到多音字可能会有点问题,据项目具体情况而定,如果多音字很重要的话可以找个多音字字典结合使用一下
HexUzHoNG
2008-04-15
NB!
应用三:关键词筛选
好像不可以连续输入首字母拼音筛选?
比如我输:h
输出:河北省 黑龙江省 河南省 湖北省 湖南省 海南省
接着输:hb
没有显示“河北省”,就提示没有匹配项了?
应用三:关键词筛选
好像不可以连续输入首字母拼音筛选?
比如我输:h
输出:河北省 黑龙江省 河南省 湖北省 湖南省 海南省
接着输:hb
没有显示“河北省”,就提示没有匹配项了?
jindw
2008-04-15
非常不错,很实用的东西
- 浏览: 15496 次

- 详细资料
搜索本博客
最新评论
-
mysql 的 AUTO_INCREMENT ...
hama 写道pi1ot 写道历史表不要用auto incr,把原表id复制过去 ...
-- by ayis -
mysql 的 AUTO_INCREMENT ...
这个概率很低的吧,除非你业务十分不稳定经常在重启中度过...
-- by edwardpro -
mysql 的 AUTO_INCREMENT ...
这问题确实有. 但是为什么你要删数据呢.为什么要赶上刚删数据时重启呢.
-- by mayongzhan -
mysql 的 AUTO_INCREMENT ...
好痛苦!!有几次遇到这个AUTO_INCREMENT在mysql中有的方法。。但 ...
-- by hua839 -
mysql 的 AUTO_INCREMENT ...
我也碰到这问题,弱弱的。 另外,楼上正解。[b][/b]
-- by 54powerman






评论排行榜