记录一次面试题

150 阅读2分钟

前一段时间面试的时候面试官给我了一张白纸和一根笔让我在纸上写代码,不过好在题目不算太难,题目是这样的

将链接上的参数转换成对象
1. 如果参数没有值,则设置值为true
2. 如果出现重复字段,则将值存入数组里
3. 如果值是数字,则将值转换为数字
4. 如果是中文的ASCII编码,则转换为中文汉字

如传入
http://www.baidu.com?name=zs&age=18&flag&age=%E5%8D%81%E5%85%AB&name=%E6%B3%95%E5%A4%96%E7%8B%82%E5%BE%92&skill=qwer&id=10086&flag

输出
{
  name: [ 'zs', '法外狂徒' ],
  age: [ 18, '十八' ],
  flag: [ true, true ],
  skill: 'qwer',
  id: 10086
}

难度到不算太大,但是当时黑鸡比较紧张也并没有想到太好的办法,最后在纸上划划写写最终写出来了下面的方法,虽然可行但是代码明显太过于臃肿,面试官给予的评价也是写的方法太笨了,不过面试官还是很宽容,接着说这也许是因为你工作年限太短,然后回去之后黑鸡也是好好的想了想这道题,然后又好好看了看自己当时写的方法,后面确实想到了更好的办法。

function parseParams (url) {
	url = decodeURI(url) 
	const queryStr = url.slice(url.indexOf('?') + 1);
	const queryArr = queryStr.split('&');
	const params = {};

	for(let i = 0; i < queryArr.length; i++){
		let item = queryArr[i].split('=');
		if(item.length === 1){
			if(params[item[0]]){
				if(Array.isArray(params[item[0]])){
					params[item[0]] = [...params[item[0]], true]
				}else{
					params[item[0]] = [params[item[0]], true];
				}
			}else{
				params[item[0]] = true
			}
		}else{
			if(!Number.isNaN(item[1] * 1)){
				item[1] = item[1] * 1
			}
			if(params[item[0]]){
				if(Array.isArray(params[item[0]])){
					params[item[0]] = [...params[item[0]], item[1]];
				}else{
					params[item[0]] = [params[item[0]], item[1]];
				}
			}else{
				params[item[0]] = item[1]
			}
		}
	}
	return params;
}

在思索了之后,黑鸡发现自己当时在判断了item的长度是1还是2其实根本没有必要,而且判断params的某个属性是不是数组也没有必要,中间的判断确实太过于繁琐了,然后黑鸡最后想到了下面的实现方式

function parseParams(url){
	url = decodeURI(url)
	const queryStr = url.slice(url.indexOf('?') + 1);
	const queryArr = queryStr.split('&');
	const params = {};

	for(let item of queryArr){
		let [k, v] = item.split('=');
		if(!v) v = true; //如果v不存在表示此参数没有值,设置为true
		if(!Number.isNaN(parseInt(v))) v = Number(v); //如果是数字字符串转换为数字
		if(params[k]){
			params[k] = [].concat(params[k], v); //如果不是第一次出现直接拼接到数组最后一项
		}else{
			params[k] = v;
		}
	}
	return params
}

修改之后黑鸡感觉优雅了很多,这也是自己的一次成长经历吧,不知道还有没有更好的方法欢迎各位大佬指出