前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端算法-解析URL字符串

前端算法-解析URL字符串

作者头像
Careteen
发布2022-02-14 16:29:31
5440
发布2022-02-14 16:29:31
举报
文章被收录于专栏:源码揭秘源码揭秘

前言

写一个程序parse,解析下面的queryString,返回一个对象

代码语言:javascript
复制
console.log(parse('a=1&b=2&c=3')) // => { a: '1', b: '2', c: '3' }
console.log(parse('a&b&c')) // => {}
console.log(parse('a[name][second]=careteen&a[company]=sohu&b=y')) // => { a: { name: { second: 'careteen' }, company: 'sohu' }, b: 'y' }
console.log(parse('color=Deep%20Blue')) // => { color: 'Deep Blue' }
console.log(parse('a[0]=1&a[1]=2')) // => { a: [ '1', '2' ] }

分析

首先要先了解url参数的规则

  • &或其他字符进行分割,且以=分割键值对
  • &=分割时可能没有值
  • =后面的值可能已经encodeURIComponent转码,需要解码
  • 可能会是一个多层级的对象a[name][second]=careteen&a[company]=sohu&b=y,需要按层级设置对象
  • 对象的键可能为一个数字a[0]=1&a[1]=2,此时应该处理返回成数组

实现

针对上述分析其规则,解析一个URL需要考虑诸多情况。

具体代码和测试用例实现

下面给出具体实现

代码语言:javascript
复制
/**
 * @desc 解析URL
 * @param {String} str 
 * @param {Object} options 
 * @param {String} options.delimiter // 分隔符
 */
const parse = (str, options = {}) => {
  let config = Object.assign({
    delimiter: '&'
  }, options)

  return str.split(config.delimiter).reduce((ret, cur) => {
    let [key, value] = cur.split('=')
    if (!value) return ret
    // ret[key] = value
    deepSet(ret, key, value)
    return ret
  }, {})
}

辅助函数

代码语言:javascript
复制
/**
 * @desc 辅助函数 深层级设置
 */
const deepSet = (ret, key, value) => {
  /* eslint-disable */
  let path = key.split(/[\[\]]/g).filter(item => !!item)
  // console.log(path)
  let i = 0
  for (; i < path.length - 1; i++) {
    if (ret[path[i]] === undefined) {
      if (path[i + 1].match(/^\d+$/)) {
        ret[path[i]] = []
      } else {
        ret[path[i]] = {}
      }
    }
    ret = ret[path[i]]
  }
  ret[path[i]] = decodeURIComponent(value)
  // console.log(ret)
}

测试用例

代码语言:javascript
复制
console.log(parse('a=1&b=2&c=3')) // => { a: '1', b: '2', c: '3' }
console.log(parse('a&b&c')) // => {}
console.log(parse('a[name][second]=careteen&a[company]=sohu&b=y')) // => { a: { name: { second: 'careteen' }, company: 'sohu' }, b: 'y' }
console.log(parse('color=Deep%20Blue')) // => { color: 'Deep Blue' }
console.log(parse('a[0]=1&a[1]=2')) // => { a: [ '1', '2' ] }

总结

解析字符串看似简单,实则考察诸多知识点

  • 使用reduce去简化流程
  • 考虑URL规则满足各种需求
  • 检验对正则的掌握
  • 深层级对象的设置需要使用循环去合理设置
  • 区分数组和对象两种场景
  • 别忘了解码
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 分析
  • 实现
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档