JS实现输入拼音搜索中文列表

JavaScript025

JS实现输入拼音搜索中文列表,第1张

最近工作中接到了一个需求:一个项目列表,项目名称可能有中文可能有英文,如果是中文的话,需要实现用户输入项目的拼音即可筛选到对应项目的功能。

完成了之后觉得可以在公众号里给大家分享一下,给有需要的人一个参考吧。

项目框架用的是react,所以先creat-react-app

比如create-react-app pinyin

渲染选择框的组件用的是antd的Select组件,所以需要先引入antd,具体引入的方法参照antd官方文档,已经写得很清楚了

以上准备工作做好后,目前的目录结构应该如下图所示:

├── README.md

├── package.json

├── package-lock.json

├── config-overrides.js

├── public

│    ├── favicon.ico

│    ├──index.html

      └── manifest.json

├── src

│   ├── App.css

│   ├── App.js

│   ├── App.test.js

│   ├── index.css

│   ├── index.js

│   ├──logo.svg

│   └── registerServiceWorker.js

现在在src文件夹下新建一个components文件夹,components文件夹中新建一个SelectPinYin文件夹,SelectPinYin文件夹下新建一个index.js和PinYin.js

PinYin.js文件中主要放置拼音和各个拼音对应的中文字符串,方便组件调用

export const SimplePinYin = {

py: [

        [ 'a','阿啊呵腌吖锕啊呵嗄啊呵啊呵阿啊呵' ],

        [ 'ai','哀挨埃唉哎捱锿呆挨癌皑捱矮哎蔼霭嗳爱碍艾唉哎隘暧嗳瑷嗌嫒砹' ],

        [ 'an','安谙鞍氨庵桉鹌厂俺铵揞埯案按暗岸黯胺犴' ],

        [ 'ang','肮昂盎' ],

        [ 'ao','熬凹熬敖嚣嗷鏖鳌翱獒聱螯廒遨袄拗媪奥澳傲懊坳拗骜岙鏊' ],

        [ 'ba','八吧巴叭芭扒疤笆粑岜捌八拔跋茇菝魃把靶钯把爸罢霸坝耙灞鲅吧罢' ],

        [ 'bai','掰白百摆伯柏佰捭败拜呗稗' ],

        [ 'ban','般班搬斑颁扳瘢癍版板阪坂钣舨办半伴扮瓣拌绊' ],

        [ 'bang','帮邦浜梆膀榜绑棒膀傍磅谤镑蚌蒡' ],

[ 'bao','包胞炮剥褒苞孢煲龅薄雹保宝饱堡葆褓鸨报暴抱爆鲍曝刨瀑豹趵' ],

        [ 'bei','背悲杯碑卑陂埤萆鹎北被备背辈倍贝蓓惫悖狈焙邶钡孛碚褙鐾鞴臂呗' ],

...

]

}

内容太多,只能复制这样一小部分,其余部分可以参考下面这条链接,然后改成上面那种格式就可以了。

http://www.cnblogs.com/meteoric_cry/p/5954547.html

接下来开始写组件

要做到拼音搜索匹配到中文,所以调用this.selectPinYin函数,下面开始写selectPinYin函数

当input为中文时:

return option.props.children.toLowerCase().indexOf( input.toLowerCase() ) >= 0

当input为字母时:

const value = option.props.children.toLowerCase().split( '' )

const newValue = value.map( item =>this.chineseChangePY( item ) ).join( '' )

return newValue.indexOf( input.toLowerCase() ) >= 0

思路:

①    将列表中的每项内容,即option.props.children转成小写(万一不全是中文),然后进行分割,split('')把字符串转成数组

②    遍历得到的数组,并把每一个元素传递给chineseChangePY函数

③    chineseChangePY函数的作用:如果元素不是中文,直接返回;如果是中文,遍历PinYin.js中的数组,与每个子数组的第二个元素即中文字符串对比,如果元素在这个中文字符串里,返回中文字符串所在数组的第一个元素,即所需要的拼音

④    将处理过的数组转成字符串

⑤    和input进行对比,存在返回true,不存在返回false

bug说明: 比如遇到生僻字的时候,PinYin.js中没有收录进这个中文,就无法匹配。比如遇到多音字的时候,“藏”:既可以cang也可以zang,cang排在zang前面,当遍历匹配的时候遇到cang就已经返回了,所以如果有用户输入zang就匹配不到藏字。

如果有更好的方法,欢迎讨论交流。

有可能是字符串拼接的时候导致判断条件不同的原因。

如果两个操作数都是字符串类型,则按照字符编码进行比较。如果第一个字符编码相同,则比较第二个。

如果两个都是数值类型,则按照大小比较。

如果其中一个是数值类型,则将另一个基本数据类型调用Number函数,将其隐式强制转换为数值类型。

如果其中一个是布尔类型,则先调用Number函数将其隐式强制转换为数值类型,然后再比较看。

这个说简单不简单,说难不难,如果你想非常精确,非常优化的提示,需要很多人工干预,

如果是完全自动化处理也是可能的,关键是你要用哪一门后台语言。本人只擅长PHP,先讲下原理。

就是把你首先你要筛选出一堆提示关键字, 按拼音的字母排序,然后,每次ajax查询时候如果用户输入纯英文,就跟汉字首字母比较。比如你给的JS,匹配字“即时,检索,解释"什么的,就可以显示。

这时候你要说了,我怎么取汉字首字母,难道手工打上去并排序么。这其实可以用程序来取。百度找“jsp把汉字转拼音”或者php把汉字转拼音,这些都有现成的函数。做一次2次开发,用个页面接收你输入的关键字取每个拼音首字母,然后输入到数据库关键字表中,输出到txt、xml、内存缓存做关键词提示的时候可以再按拼音和优先级排序,mysql是可以用拼音排序的。比如下面的数据项(仅供参考,你喜欢怎么写都行)

建设 /jianshe / JS / 0 / 1

这样就一行。第一项主键,第二项是全拼音索引,用来排序和备用,最后2个是查询的次数和手工的加权数,

然后服务器查询的时候,依靠第三项JS,查询出一堆符合的汉字,结合后2位数算出优先级大小显示前10个就可以。用户查询后获取他用的关键字,然后查询次数+1。

你既然写过这类程序,这个检索汉字功能关键就是转拼音的2次开发,取首字母并排序生成一个新型的词库。也不算太有差异。