JavaScript字典与集合详解

  今天和大家讲讲JS“字典”。所谓的JS“字典”其实和显示中常用汉语字典不一样,编程中的字典类似,两者都有一个特点,就是一一对应(yi yi dui ying),或者说是映射

  日常中的字典通常以**【键,值】** 对的形成存储,主要是由于以键值对的形式存储,这样的话更有利于可以通过key来获取value

  比如存储用户信息:

  {
  'username': '一碗周',
  'age': 18
  }
  JavaScript中的字典

  在JS的字典,其实就是在ES6中新增Map,并非字典,且map不是翻译成地图,而是映射。

  示例代码如下:

  // 创建一个字典
  const map = new Map()
  // 往字典中存储信息
  map.set('username', '一碗周')
  map.set('age', 18)
  console.log(map) // Map(2) { 'username' => '一碗周', 'age' => 18 }

  字典的应用实例

  我们想要将一个算法题:有效的括号,内容就是判断给定字符串中的括号是否匹配,匹配返回true,否则返回false。

  解题思路如下:

  对字符串是否为偶数要做判断,当不是欧数值时返回false,依据是括号都是成对出现的;

  新建一个栈;

  先遍历字符串,遍历到每一项时如果时左括号,将其压入栈;如果是右括号,与栈顶对比,如果相匹配则出栈,不匹配则返回false。

  我们原来的解法:

  /**
  * @param {string} s
  * @return {boolean}
  */
  var isValid = function(s) {
  if (s.length % 2 !== 0) return false
  const stack = []
  for(let i = 0; i<s.length; i++) {
  const c = s[i] // 记录当前项
  if (c === '(' || c === '[' || c==='{') {
  stack.push(c)
  } else {
  const t = stack[stack.length - 1] // 获取栈顶元素
  if (
  (t === '(' && c === ')') ||
  (t === '[' && c === ']') ||
  (t === '{' && c === '}')
  ) {
  stack.pop()
  } else {
  return false
  }
  }
  }
  // 如果为0表示全部匹配,有剩余则表示不匹配
  return stack.length === 0
  };

  上面代码中判断条实太长了,我们需要用字典这个方式来优化对应写法,

  实现代码如下:

  /**
  * @param {string} s
  * @return {boolean}
  */
  var isValid = function(s) {
  // 1. 判断字符串的长度是否为偶数,不为偶数直接返回false,因为括号都是成对出现的;
  if (s.length % 2 !== 0) return false
  const stack = []
  const map = new Map() // 将所有括号的对应关系存储在字典中
  map.set('(', ')')
  map.set('[', ']')
  map.set('{', '}')
  for(let i = 0; i<s.length; i++) {
  const c = s[i] // 记录当前项
  // 判断是否存在 key 也就是左括号,如果存储,将左括号存储在栈中
  if (map.has(c)) {
  stack.push(c)
  } else {
  const t = stack[stack.length - 1] // 获取栈顶元素
  if (map.get(t) === c) { // 获取最后一个左括号,判断是否与右括号匹配
  stack.pop() // 出栈
  } else {
  return false
  }
  }
  }
  // 如果为0表示全部匹配,有剩余则表示不匹配
  return stack.length === 0
  };

  上面代码主要是优化if条件判断语句。

  集合  

  集合是由一组无序且不重复的元素构成。集合就是无序且不重复的特殊数值,因此就不能通过下标的方式进行访问,且不会出现重复数值;

  JS中的集合

  在JavaScript中可以为集合提供一个数据结构,就是Set,MDN中的描述如下:

  Set对象是值的集合,意思也就是按照插入的顺序迭代它的元素。Set中的元素只会出现一次,即Set中的元素是唯一的。

  集合中的操作

  在集合中主要有以下场景操作:

  添加元素到集合中;

  在集合中删除某元素;

  判断元素是否在集合中;

  清空集合;

  求交集、并集、差集;

  除了最后一种Set对象就为我们提供了对应的方法,示例代码如下:

  const arr = [1, 2, 3, 2, 3, 4, 5]
  // 利用set实现去重
  const set = new Set(arr) // [1, 2, 3, 4, 5]
  // 往集合中添加元素
  set.add(3) // [1, 2, 3, 4, 5] 添加失败,集合中不允许出现重复元素
  set.add(6) // [1, 2, 3, 4, 5, 6]
  // 判断元素是否在集合中
  set.has(2) // true
  set.has(7) // false
  // 删除集合中的元素
  set.delete(1) // [2, 3, 4, 5, 6]
  // 清空集合
  set.clear()

  交集、并集、差集的封装

       我们现在来注释下:

  并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合

  交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合

  差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合

  下图可以体现三者关系:

1.png

  封装代码如下:

  // 求两个集合的并集
  export function union(setA, setB) {
  let _union = new Set(setA)
  for (let elem of setB) {
  _union.add(elem) // 因为集合中不存在重复元素
  }
  return _union
  }
  // 求两个集合的交集
  export function intersection(setA, setB) {
  let _intersection = new Set()
  for (let elem of setB) {
  if (setA.has(elem)) {
  _intersection.add(elem)
  }
  }
  return _intersection
  }
  // 求两个集合的差集
  export function difference(setA, setB) {
  let _difference = new Set(setA)
  for (let elem of setB) {
  _difference.delete(elem)
  }
  return _difference
  }

  其实封装的这三个方法全部利用了集合不能重复的特性。

      内容已讲述完毕,后续更多精彩内容,请多多关注。

原创文章,作者:网友投稿,如若转载,请注明出处:https://www.cloudads.cn/archives/3961.html

发表评论

登录后才能评论