获取url参数

题目描述
获取 url 中的参数
1.指定参数名称,返回该参数的值 或者 空字符串
2.不指定参数名称,返回全部的参数对象 或者 {}
3.如果存在多个同名参数,则返回数组
示例1
输入

http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe key

输出

[1, 2, 3]

解法1:

function getUrlParam(sUrl, sKey) {
    var str = sUrl.split('?')[1].split('#')[0].split('&')
    var obj = {};
    str.forEach(item => {
        var [key, value] = item.split('=');
        if(obj[key] === void 0){
            obj[key] = value;
        } else {
            obj[key] = [].concat(obj[key], value);
        }
    });
    return sKey === void 0?null:obj[sKey]||null;
}
var sUrl = "http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe";
sKey = "key";
console.log(getUrlParam(sUrl, sKey));

思路:
逐段分割,首先利用去除前面的协议和域名部分,然后在利用#去除锚部分,剩下的就是需要进行分析的参数部分,本题的核心思想是建立对象,以参数名作为属性,以参数值作为值;得到了锚部分之后,利用=分割为要获取的参数名和参数值,如果是首次获取到该参数名,则直接将对应的参数值赋予,否则进行加入该值;这里一个冷知识,concat合并两个数组,但是这里的obj[key]在首次加入之后却只是一个string类型的值,因此直接使用该方法会得到连接的字符串,所以可以使用上面的方法,每次都建立一个新的数组,然后存入上个版本的obj[key]vlaue,再与空数组连接,得到一个新数组,最后进行一部判断,sKey 是否为空,obj是否为空,虽然输出的是一个存放字符(串)的数组,但是在可以A,我修改了下用Number进行转化,结果超时,这是很让人有疑惑的地方。

解法2:

function getUrlParam(sUrl, sKey) {
var result, sParam = {};
    sUrl.replace(/(\?|&)(\w+)=(\w+)/g, function(k0, k3, k1, k2){
        console.log(k0, k1, k2, k3);
        sParam[k1] === void 0 ? sParam[k1] = k2 : sParam[k1] = [].concat(sParam[k1], k2);
    });
    console.log(sUrl);
    sKey === void 0 || sKey === '' ? result = sParam : result = sParam[sKey] || '';
    return result;
}
var sUrl = "http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe";
sKey = "key";
console.log(getUrlParam(sUrl, sKey));

思路:正则表示,再利用replace第二个参数子表达式的语法;首先看正则,第一个是匹配一个或者&,对应参数部分的每一个参数,然后是参数名任意字符、数字和下划线,再匹配等号,最后匹配参数值,要求和参数名相同,注意需要全局匹配;关于replace第二个参数的说明,W3school给出了解释:

ECMAScript v3 规定,replace() 方法的参数 replacement,可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。最后一个参数是stringObject 本身。

也就是说,在函数中k0,k1,k2, k3分别代表原字符串,(?|&),(\w+),(\w+),正则表达式是通过()来划分子表达式的,但是这里并未用到(?|&),因此可以列举出来作为之后子表达式的引用,之后的思路与解法一相同。

超时的一发:
var sUrl = “http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe”;
sKey = “key”;
function getUrlParam(sUrl, sKey) {
var arr = [];
while(sUrl.indexOf(sKey) !== -1){
var start = sUrl.indexOf(sKey)+sKey.length+1;
var end = sUrl.indexOf(’&’);
// console.log("strat = ", start);
// console.log("end = ", end);
var str = sUrl.substring(start, end);
//console.log("str = ", str);
arr.push(Number(str));
sUrl = sUrl.slice(sUrl.indexOf(’&’)+1);
//console.log(sUrl);
}
return arr;
}
console.log(getUrlParam(sUrl, sKey));
这里就不做代码引用来误导了,虽然结果相同,但是判定超时,感觉用substring来截取要更好耗时一些,JS的引擎是C++来实现的,底层的算法可能是O(n)的时间复杂度,所以相对于split来说,还是更倾向于前者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值