上来先贴一段代码
function sortString(str,s){
if(str && typeof str === 'string' && str.length > 1 && (s = s||',')){
return str.split(s).filter(function (a,i,arr){
return arr.indexOf(a) === arr.lastIndexOf(a) || i === arr.indexOf(a);
}).sort(function(a,b){
return +a - +b;
}).reduce(function (a,b){
return [a,b].join(s);
});
}
return str;
}
恩,以上就是今天的全部内容
var str = sortString('01,02,03,03,02,01,05,06,04');
console.log(str)
以上测试代码的输出结果是:
"01,02,03,04,05,06"
看懂了就不用继续了,我废话比较多。
就这样是不是太干了一点?
稍微解释一下好了,这段代码要做的事情就是,把一段类似于‘01,01,03,06,01,02,06,02,03,04,09,01’这样的字符串,用“,”分开,然后去重,排序,重新拼接起来
这样的好处在于可以得到唯一的结果
先说一下这段代码的来历好了,上回客户给了一个sql语句,查询出来的结果有个字段就差不多长我上面给的这个字符串的样子,这个是一个code拼接起来的,也就是查询的是主表,然后将子表的某个字段拼接成这个样子了,子表数量是不一定的(子表本身的code也是拼接的,所以没法distinct)
这样一个表格
code | text |
---|---|
01 | 一型 |
02 | 二型 |
03 | 三型 |
子表数据
数据 |
---|
01,03 |
02,03 |
01,02,03 |
主表数据就变成了
01,03,02,03,01,02,03
好了,来历说完了,下面开始解释一下这段代码
代码的作用上面说完了
这里开始说明
参数
str :原始字符串
s :字符串中间的间隔串
关于 if 的用法
我在if中写的语句是这样的
if(str && typeof str === 'string' && str.length > 1 && (s = s||','))
以&&符号间隔
第一段这里会将str转成bool值
第二段是typeof的用法,没啥好说的,注意typeof给出来的结果都是小写的就好了
第三段是确定已经是一个字符串了,所以可以判断长度了,长度小于1就没啥好做的了,不操作直接返回就好
第四段是(s = s||','),首先解释s = s||','这里说的是为了避免不传参数s,默认值是s,||符号起隔断作用,如果s有值,并且不会被转成false,则s赋值成自己本身,如果s可以被转成false(null,undefined,0,''[空字符串]等),则将s赋值成',',也就是说如果你的 s 就是逗号,可以不传。
然后稍微解释一下这里放一个(s=s||',')是什么意思(好啦,我承认这只是装个×,你把这一段去掉,放到if里面第一行,没有任何问题),我知道你们应该都能看懂连续的等号复制:a=b=c=1,就是说将1赋值给c,再将c赋值给b,b给a。你会发现:我不写'a='是可以的,换一个写法a=(b=(c=1))也是没问题的。明白了么?c=1这个表达式也是有结果的,他的结果就是1,所以上面s=s||','的值就是s||','了,然后因为这里是在if的条件中,所以一定会被转成bool值进行判断,不管怎样一定是true,所以放到if里头其实没什么实际意义。就是吓唬一下新人。
if解释完,开始重头戏 array原型上的一些好方法
----不要一看原型就被吓着了,这里不讲原型的问题
javascript中string类型的一个超级好用的方法split,作用是将一个string切割成一个数组,通过你设置的参数来割开,不多解释
所以第一步将str分隔成了数组
调用数组的 filter 方法,这个方法有个参数(回调函数),它会对数组的每一个元素调用一次回调函数,将回调函数返回的结果为true的元素收集起来作为新的数组返回,回调函数的参数:
a :当前元素
i :当前元素的索引
arr:整个数组
数组方法indexOf,获取元素的索引,lastIndexOf,元素最后一次出现的索引,这俩相等,元素唯一,不需要去重,如果这俩不相等,说明元素有重复,这时候就需要去重,当然选第一个放进去会比较简单,所以如果当前元素的索引 i 与当前元素的第一次出现的索引相等,说明是第一个,这个是可以加进来的,其他的不可以,去重就做完了
然后是调用数组的 sort 方法,排序,回调函数有两个参数,a,b,回调函数定义a和b的比较结果,返回0表示相等,返回 正数 a比较大,返回 负数 b比较大,所以我的回调函数里头直接将两个数减了一下,然后我在减之前做了一个小运算,+a和+b,这是快速的将一个字符串转换成数字,如果失败了,得到的结果是NaN
最后的reduce似乎又是装x的了(汗,我刚刚才注意到可以直接join),也是稍微解释一下吧,reduce这个词的意思是简化,但是这个方法可一点都不简单,我只给了一个参数,但是这个方法可以接收两个参数,第一个是回调,第二个是初始值(也就是第一次调用回调的时候参数a的值)
回调函数参数(我只用到了两个,但是有四个),可以参阅这里Array.prototype.reduce
按顺序:
previousValue
上一次执行的结果,第一次的话就是给的初始值或者第一个值
currentValue
当前值
currentIndex
当前值在数组中的索引
array
数组本身
这个方法就是不停的把数组的元素和上一次执行的结果交给回调,直到最后剩下一个元素作为返回值,在程序里头我把两个字符串给join起来,然后交给下一次又join上下一个元素,得到的结果跟直接join是一样的
另可参见ES5中新增的Array方法详细说明
好吧,既然最后那个方法白用了,那就补一段代码好了
我现在有一个数组:
var arr = [
{id:1,text:'一'},
{id:2,text:'二'},
{id:3,text:'三'},
{id:4,text:'四'},
{id:5,text:'五'}
];
我需要将其中的id取出来拼成一个字符串
可以咋做呢?
答案就是:
var str2 = arr.reduce(function (a,b,i,arr){
return [a,b.id].join();
},'').substr(1);
console.log(str2);
当然你也可以用map来做
var str2 = arr.map(function (a) {
return a.id;
}).join()
console.log(str2);
以上