Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 105 题:编程题 #177

Open
yygmind opened this issue Jul 14, 2019 · 48 comments

Comments

@yygmind
Copy link
Contributor

@yygmind yygmind commented Jul 14, 2019

url有三种情况

https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33
https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33
https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33

匹配elective后的数字输出(写出你认为的最优解法):

[] || ['800'] || ['800','700']
@LiuL0703

This comment has been minimized.

Copy link

@LiuL0703 LiuL0703 commented Jul 14, 2019

function getUrlValue(url){
    if(!url) return;
    let res = url.match(/(?<=elective=)(\d+(,\d+)*)/);
    return res ?res[0].split(',') : [];
}
@zcdll

This comment has been minimized.

Copy link

@zcdll zcdll commented Jul 15, 2019

const urls = [
  "https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33",
  "https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33",
  "https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33",
];

function getElective(url) {
  const reg = new RegExp("(^|&)elective=([^&]*)(&|$)", "i");
  const r = url.substr(1).match(reg);

  if (r != null) {
    return r[2] ? r[2].split(",") : [];
  }

  return [];
}

urls.forEach((url) => {
  const result = getElective(url);
  console.log(result, "---result");
});
@chenyuwulu

This comment has been minimized.

Copy link

@chenyuwulu chenyuwulu commented Jul 15, 2019

考虑到是大厂级别的前端要求,有这么几点:
1,elective是跟在一堆空值后面,所以要效率最高的排除掉前面的匹配。
2,在匹配完elective的值之后,&后面的匹配就需要立刻停止,停止性能消耗
3,第三个的值中带了逗号,也要考虑其他符号的可能性。

@GitHdu

This comment has been minimized.

Copy link

@GitHdu GitHdu commented Jul 15, 2019

 new URLSearchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33').get('elective')
@gmkgmk

This comment has been minimized.

Copy link

@gmkgmk gmkgmk commented Jul 15, 2019

new URL
("https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=700,800&local_province_id=33")
.searchParams.get("elective")
.split(",")
.filter(e=>e)
.map(e=>e)

@libin1991

This comment has been minimized.

Copy link

@libin1991 libin1991 commented Jul 15, 2019

image

@habc0807

This comment has been minimized.

Copy link

@habc0807 habc0807 commented Jul 15, 2019

function searchParams(url) {
	const searchParams = new URLSearchParams(url)
	const getElective = searchParams.get('elective')

	if(getElective) {
		return getElective.split(',').filter(item => item)
	} else {
		return []
	}
}
searchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33') // []
searchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33') // ["800"]
searchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33') // ["800","700"]
@cloudMokie

This comment has been minimized.

Copy link

@cloudMokie cloudMokie commented Jul 15, 2019

const urls = [
"https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33",
"https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33",
"https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33",
];
urls.forEach(url => {
console.log(new URLSearchParams(url).get('elective').split(','));
});

@HduSy

This comment has been minimized.

Copy link

@HduSy HduSy commented Jul 15, 2019

`
function searchParams(url) {
const searchParams = new URLSearchParams(url)
const getElective = searchParams.get('elective')

if(getElective) {
	return getElective.split(',').filter(item => item)
} else {
	return []
}

}
searchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33') // []
searchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33') // ["800"]
searchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33') // ["800","700"]
`

@Yxiuchao

This comment has been minimized.

Copy link

@Yxiuchao Yxiuchao commented Jul 15, 2019

模仿第一位大佬的做法
var getUrlValue = function (urls) {
if (!urls) return;
let tempRes = /(?<=elective=)(\d+(.\d)*)/g.exec(urls);
return tempRes ? tempRes[0].split(',') : []
}

@zyrepo

This comment has been minimized.

Copy link

@zyrepo zyrepo commented Jul 15, 2019

可惜啊,大部分公司要兼容到ie11

屏幕快照 2019-07-15 上午11 16 05

@yannyyang

This comment has been minimized.

Copy link

@yannyyang yannyyang commented Jul 15, 2019

function trans(str){
let arr = str.split("?")[1].split("&");
for(let i = 0 ; i< arr.length; i++){
if(arr[i].split("=")[0]==="elective"){
target = arr[i].split("=")[1];
}
}
return target.split(",");
}

@IAMLOVER

This comment has been minimized.

Copy link

@IAMLOVER IAMLOVER commented Jul 15, 2019

 new URLSearchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33').get('elective')

IE浏览器不支持呀

@zyrepo

This comment has been minimized.

Copy link

@zyrepo zyrepo commented Jul 15, 2019

function getUrlValue(url, param) {
	let query = url.split('?')[1]
	if(query) {
		let m = query.split('&')
		for(let i = 0; i<m.length; i++){
			let n = m[i].split('=')
			if(n[0] === param) { 
				return n[1] 
                        }
		}
	}
	return undefined
}
@weiweixuan

This comment has been minimized.

Copy link

@weiweixuan weiweixuan commented Jul 15, 2019

模拟第一位大佬的做法
var getUrlValue = function(urls){
if(!urls)return;
let tempRes = /(?<= select =)(〜d+(。\ d)*)/ g.exec(urls);
返回tempRes?tempRes [0] .split(','):[]
}

正则里写的是啥意思啊,好炫,看不懂

@weiweixuan

This comment has been minimized.

Copy link

@weiweixuan weiweixuan commented Jul 15, 2019

这么写好搓啊,高级的不会,哈哈哈

/*url有三种情况
      https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33
      https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33
      https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33
      匹配elective后的数字输出(写出你认为的最优解法):
      [] || ['800'] || ['800','700']*/
      let url =
        'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=22,44&local_province_id=33'
      function getElective(url, key) {
        let str = url.slice(url.indexOf(key) + ++key.length)
        let res = str.indexOf('&') > -1 ? str.split('&')[0] : str
        if (res === '') return []
        return res.indexOf(',') > -1 ? res.split(',') : [res]
      }
      let res = getElective(url, 'elective')
      console.log(res)
@IAMLOVER

This comment has been minimized.

Copy link

@IAMLOVER IAMLOVER commented Jul 15, 2019

有没有大佬解释下第一位给的正则啊?看不懂呀

@IAMLOVER

This comment has been minimized.

Copy link

@IAMLOVER IAMLOVER commented Jul 15, 2019

有没有大佬解释下第一位给的正则啊?看不懂呀
(/(?<=elective=)(\d+(,\d+))/)
其中:(?<=elective=) 是指匹配以elective=开头的字符串;
(\d+(, \d+)
)指匹配数字开头,可能不定数量逗号分隔后是数字的字符串。

@tuzilingdang

This comment has been minimized.

Copy link

@tuzilingdang tuzilingdang commented Jul 15, 2019

function getUrlValue(url, targetKey) {
    if (!url || !targetKey) return []

    let reg = new RegExp(`&?${targetKey}=(\\d*,?)*&?`)
    let matchStr = reg.exec(url)
    let val = matchStr.length && matchStr[0].replace(/&/g,'').split('=').length >= 2 ? matchStr[0].replace(/&/g,'').split('=')[1] : ''
    return val ? val.split(',') : []
}
@lhyt

This comment has been minimized.

Copy link

@lhyt lhyt commented Jul 15, 2019

用Url对象是开挂了。其实还可以创建a标签直接搞,也是类似Url对象的效果。用原始的正则也很简单

function getQueryFromUrl(key, url) {
  const matches = url.match(new RegExp(`(\\?|&)${key}=([^&]*)(&|$)`));
  return !matches ? [] : matches[2].split(',');
}

getQueryFromUrl('elective' , 'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33')
@YYJay

This comment has been minimized.

Copy link

@YYJay YYJay commented Jul 15, 2019

function getQueryParam(queryString) { // 默认必有elective字段
  const electiveString  = queryString
    .split("&")
    .filter(str => str.includes('elective='))[0]
  const result  = electiveString
    .split("=")[1] // value
    .split(',') 
    .filter(item => item) 
  return result 
}

@J-DuYa

This comment has been minimized.

Copy link

@J-DuYa J-DuYa commented Jul 15, 2019

// 匹配url后面的关于某字段的值
export async function getUrlParam(url = "", param = "") {
  let result = "";

  // 比如取得"name"这个字段的参数
  if (!url || !param) {
    return "";
  }

  // 方法一 result = new URLSearchParams(url).get(param); // 内置api方法实现

  // 方法二
  let _a =
    url.split("?").length > 1
      ? url
          .replace("?", "?&")
          .split("?")
          .join()
          .replace(/\&/g, "&&&")
          .split("&&")
      : [url]; // 这里取数组第一个参数后的内容
  _a.length > 1 ? (_a = _a.slice(1)) : (_a = []);
  _a.forEach(item => {
    if (item.indexOf(param + "=") > -1) {
      result = item.split("=")[1];
    }
  });
  return result.split(",").length === 1 ?  (result.split(",")[0] === "" ? [] :  result.split(",")) :  result.split(",");
}
@rhpwyhrr

This comment has been minimized.

Copy link

@rhpwyhrr rhpwyhrr commented Jul 15, 2019

var getParams=function(url,{data='elective'}={}){
let params = url.split(data+'=')[1];
if(params == undefined) return undefined;
let val = params.split('&')[0];
return val==''?[]:val.split(',');
}

@630268501

This comment has been minimized.

Copy link

@630268501 630268501 commented Jul 15, 2019

function getword(url,word){
var test =new RegExp(word+'=([^&]*)(&|$)');
var ele = url.match(test)[1];
return ele?ele.split(","):[];
}
啥是大厂,没进去过。可能有以下需求:
1.可以扩展换url,换字段;
2.要快;
3.还得防止各种报错

@MissNanLan

This comment has been minimized.

Copy link

@MissNanLan MissNanLan commented Jul 15, 2019

 let ur =  new URLSearchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33').get('elective')

这个很厉害,有又学到一招

这个正则表达式

function getUrlValue(url){
    if(!url) return;
    let res = url.match(/(?<=elective=)(\d+(,\d+)*)/);
    return res ?res[0].split(',') : [];
}

这个正则表达式<=是零宽度断言的写法,断言 elective=有无内容,是匹配elective=的字符的

@lipanshan

This comment has been minimized.

Copy link

@lipanshan lipanshan commented Jul 16, 2019

const getUrlValue = (url, key) => {
const reg = new RegExp((?<=${key}=)([^&]*)(?=&));
const result = url.match(reg);
return result ? result[1] : result;
}

@james9527

This comment has been minimized.

Copy link

@james9527 james9527 commented Jul 16, 2019

get了,URLSearchParams这个API是好API👍
image
浏览器兼容性如下(红色块为不支持的版本):
WechatIMG487

@GDUT-Rex

This comment has been minimized.

Copy link

@GDUT-Rex GDUT-Rex commented Jul 16, 2019

var httpString ='https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33'
var match = /elective=/g
httpString.split(match)[1].split('&')[0].split(',')
@MoveZZG

This comment has been minimized.

Copy link

@MoveZZG MoveZZG commented Jul 16, 2019

function getElective(url) {
return /elective=(?=(\d+(,\d+)*))/.test(url) ? RegExp.$1.split(',') : []
}

@HeyShinner

This comment has been minimized.

Copy link

@HeyShinner HeyShinner commented Jul 16, 2019

function getEelective(url) {
return (/elective=(?=(\d+(,\d+)*))/.test(url)) ? RegExp.$1.split(',') : []
}

函数名单词是不是写错啦~小问题哈哈

@Mini-Web

This comment has been minimized.

Copy link

@Mini-Web Mini-Web commented Jul 16, 2019

var urls = [
  'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33', 
  'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33', 
  'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33'
];
var separator = ',';
var getUrlParamsOpt = {
    specialParams: {
      elective: electiveHandler
    }
};

urls.forEach(url => {
    const { elective } = getUrlParams(url, getUrlParamsOpt);
    const otherElective = new URLSearchParams(url).getAll('elective').join(separator);

    console.log( 'elective:', elective, 'otherElective:', otherElective ? otherElective.split(separator) : []);

}
)

function electiveHandler(value) {
    return !value ? [] : value.split(separator);
}

function getUrlParams(url, opt={}) {
    const params = {};

    if (typeof url !== 'string' || !url) {
        return params;
    }

    const { specialParams = {} } = opt;
    const searchParams = (url.split('?')[1] || '').split('&').map(convert);

    searchParams.forEach(({key, value})=>{
        if (key in params) {
            params[key] = [].concat(params[key], value);
        } else {
            params[key] = value;
        }
    }
    )

    return params;

    function convert(param) {
        let[key, value] = param.split('=');

        if (typeof specialParams[key] === 'function') {
            value = specialParams[key](value);
        }

        return ({
          key,
          value
        })
    }
}
@wingmeng

This comment has been minimized.

Copy link

@wingmeng wingmeng commented Jul 17, 2019

思路:

  1. 利用 a 标签过滤出 url 中的 search 参数,防止 url 中的其他不可控内容干扰,降低下一步中正则匹配的复杂度;
  2. 构建正则表达式,来捕获分组;(形如:/(?<=[?&]elective=)(\d*)(?:(?:[^&]{1})(\d+))*/
  3. 将捕获到的分组数组进行过滤处理(去掉第 0 项和空值)。

上码:

var testUrls = [
  'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33',
  'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33',
  'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33',
  'a.com?hello=123|456&world=789'
];

function getSearchParams(url, key) {
  var link = document.createElement('a');
  link.href = url;
  var params = link.search;
  link = null;

  if (params) {
    var reg = new RegExp('(?<=[\?&]' + key + '=' + ')(\\d*)(?:(?:[^&]{1})(\\d+))*');
    var result = params.match(reg);

    // console.log(reg);
    
    return result.filter(function(s, index) {
      return index > 0 && s;
    });
  }

  return null;
}

console.log(getSearchParams(testUrls[0], 'elective'));  // []
console.log(getSearchParams(testUrls[1], 'elective'));  // ["800"]
console.log(getSearchParams(testUrls[2], 'elective'));  // ["800", "700"]
console.log(getSearchParams(testUrls[2], 'local_province_id'));  // ["33"]
console.log(getSearchParams(testUrls[3], 'hello'));  // ["123", "456"]
console.log(getSearchParams(testUrls[3], 'world'));  // ["789"]
@yanzhandong

This comment has been minimized.

Copy link

@yanzhandong yanzhandong commented Jul 17, 2019

(new URLSearchParams('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33')).get('elective').split(',')

简单就一行的事 如果需要高效率什么的就写正则

@linlinyang

This comment has been minimized.

Copy link

@linlinyang linlinyang commented Jul 17, 2019

`var url1 = 'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33',
url2 = 'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33',
url3 = 'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33';

    function getElectiveValue(url){
        let matches = url.match(/(?<=(^|&)?elective=)(.+)(?=&)/ig);
        return matches ? matches[0].split(',') : [];
    }

    console.log(getElectiveValue(url1));
    console.log(getElectiveValue(url2));
    console.log(getElectiveValue(url3));`
@Banlangenn

This comment has been minimized.

Copy link

@Banlangenn Banlangenn commented Jul 18, 2019

function getUrlValue(url){
    if(!url) return;
    let res = url.match(/\d+(?=(,|&))/g)
    return res ? res : []
}

不考虑相似结构

@wlk23wlk

This comment has been minimized.

Copy link

@wlk23wlk wlk23wlk commented Jul 18, 2019

function searchStr(str){
        var matchStr = /elective=\S*\&/.exec(str);
        return matchStr?matchStr[0].slice(9,this.length-1).split(","):[];
}
@gongph

This comment has been minimized.

Copy link

@gongph gongph commented Jul 18, 2019

总结了五种方法-JavaScript获取地址栏查询参数方式汇总来实现上面的面试题,但性能,兼容性,代码量上来看还是使用正则匹配。感兴趣的可以移步。

@mx623303468

This comment has been minimized.

Copy link

@mx623303468 mx623303468 commented Jul 19, 2019

function getURLParams(url, param) {
  return new URLSearchParams(url).get(param).split(',')
}
@leesunner

This comment has been minimized.

Copy link

@leesunner leesunner commented Jul 19, 2019

function formatUrl(url,str){
let StrArr = url.match(/elective=(\d|,)/g)[0].replace(/elective=/g,'').split(',');
return StrArr
}
formatUrl(url,'elective')
单纯这题 就不做严谨的数据检验什么的了,写下自己的答案
下面附录一个自己的简单的url参数转对象的
function urlToObj(url){
let arr = url.match(/[^?&]\w
=(\d|,)*/g),obj =new Object();
arr.forEach(x=>{
let index = x.indexOf('='),
name = x.slice(0,index),
value = x.slice(index+1,x.length);
obj[name] = value;
}
)
return obj
}
urlToObj(url);

@qiannianchong25

This comment has been minimized.

Copy link

@qiannianchong25 qiannianchong25 commented Jul 23, 2019

let urlArr=[
'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33',
'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33',
'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33'
];
function getKey(url,key){
  return new URL(url).searchParams.getAll(key)
}
urlArr.map(v=> getKey(v,'elective'))
@likepeach789

This comment has been minimized.

Copy link

@likepeach789 likepeach789 commented Aug 6, 2019

高赞的正则有点看不懂, 来个简单一点的。

function get(url) {
  let match = url.match(/&elective=(.*?)&/);
  return match[1].split(",");
}


@zjkblade

This comment has been minimized.

Copy link

@zjkblade zjkblade commented Aug 20, 2019

let urls = [
"https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33",
"https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33",
"https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33",
];
let regexp = /(?<=elective=)(\d+?[^\d]?\d+)?(?=&)/;
console.info(
urls.map(url => (res = url.match(regexp)[1], JSON.stringify((res ? res.split(',') : [])))).join(' || ')
);

@XJawher

This comment has been minimized.

Copy link

@XJawher XJawher commented Aug 22, 2019

const getAllParma = (url) => {
    console.time()
    let res = {};
    url.split('?')[1].split('&').forEach(element => res[element.split('=')[0]] = element.split('=')[1].split(','));
    return res;
}

getAllParma('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33')['elective']
console.timeEnd() // default: 0.10595703125ms

//高赞的答案,和我的耗时是差不多的
function getUrlValue(url) {
    console.time()
    if (!url) return;
    let res = url.match(/(?<=elective=)(\d+(,\d+)*)/);
    return res ? res[0].split(',') : [];
}

getUrlValue('https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33')
console.timeEnd() // default: 0.10107421875ms

通过 getAllParma 函数获取全部的参数,然后再获取指定的参数

@yaodongyi

This comment has been minimized.

Copy link

@yaodongyi yaodongyi commented Sep 21, 2019

let url = [
    'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33',
    'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33',
    'https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33'
];
function getNum(url) {
    return Array.from(url, (e) => [e.match(/elective=((\d|,)*?)&/)[1]])
}
console.log(getNum(url))
@youngchao

This comment has been minimized.

Copy link

@youngchao youngchao commented Sep 30, 2019

function getUrlParams(url) { /\&elective=(.*)\&/.test(url) return RegExp.$1?RegExp.$1.split(','):[] }

@Jesseszhang

This comment has been minimized.

Copy link

@Jesseszhang Jesseszhang commented Nov 22, 2019

"/\&elective=(.*)\&/g".test(url)   
@lanOrage

This comment has been minimized.

Copy link

@lanOrage lanOrage commented Dec 5, 2019

var url1 = "https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=&local_province_id=33"
var url2 = "https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800&local_province_id=33"
var url3 = "https://www.xx.cn/api?keyword=&level1=&local_batch_id=&elective=800,700&local_province_id=33"

// 匹配elective后的数字输出: [] || ['800'] || ['800','700']
var urls = [url1, url2, url3]
var reg = /elective=(([0-9]+,[0-9]+)||([0-9]+))*/g

var ports = ""
for (i = 0; i < 3; i++) {
urls[i].replace(reg, (p1, p2) => {
if (p2 === undefined) {
ports = ports + "[]"
} else {
ports = ports + || [${p2.split(",")}]
}
})
}
console.log(ports)
结果:[] || [800] || [800,700]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.