分享一道有关find与map的趣题

分享一道有关find与map的趣题

分享一道关于 find 和 map 两种循环遍历处理的趣题,认识在能用map处理问题时有多么利于优化代码执行的时间复杂度。

需求

将如下格式的原数组

const arr = ["3-69", "3-87", "5-171", "5-65", "5-99"]

改造为下面格式的结果数组

const arr = [
  {
    
    
    id: 3,
    children: ["69", "87"]
  },
  {
    
    
    id: 5,
    children: ["171", "65", "99"]
  }
]

解决方法

具体的解决方法有两种,第一种使用 reduce 和 find 方法,第二种使用 reduce 和 map 方法。
第一种方法,思路比较直接,在开发中很容易想到的常用方法,但是缺点很明显,使用了嵌套循环,导致时间复杂度为 O(n^2) , 执行时间相对较长。

const arr = ["3-69", "3-87", "5-171", "5-65", "5-99"]

const result1 = arr.reduce((prev, item) => {
    
    
  const [id, children] = item.split('-') //解构当前值
  let t = prev.find(item => item.id === id) //查找是否与原数组有匹配id
  // 存在匹配id,就推入到匹配id的 children 里面
  // 如果不存在匹配id,就推入当前项到下次 prev 数组里面
  // 需要注意,t的应用和 prev 里面匹配的项引用相同,可以直接赋值,并同步修改了 prev 里匹配项
  t ? t.children.push(children) : prev.push({
    
    id: id, children: [children]})
  return prev //返回处理好的 prev 数组
}, [])

console.log('result1 ==', result1)

第二种方法,需要理解 map 数据结构,因为 map 数据结构本身天然的优势,很适合用来通过 key 值快速查找,快速操作 key-value 结构的数据对象,因此我们可以先改造原数组对应的结果数组(改造后的数组)为 map 的数据结构,之后通过对象方法以及 map 方法得到数组结构的结果数组,其中使用了一次遍历,一次 map 方法操作,对应的时间复杂度为 O(n + n) ,也就是 O(2n) ,这样执行时间得到了大幅度的优化。

const map_data = arr.reduce((prev, item) => {
    
    
  const [id, children] = item.split('-') //解构当前值
  // 改造结果数组为 map 数据格式
  // 不匹配id,则将id作为 key, children 作为 value,一起存入 prev 对象
  // 如果匹配id,则将 children 推入到当前id下的 value 值里面
  if(prev[id]){
    
     prev[id].push(children) }
  else {
    
     prev[id] = [children] }
  return prev //返回处理好的 prev 对象
}, {
    
    })
// 通过对象下方法获取 map 数据结构的 key 值组成的数组
// 将该数组进行 map 方法执行,map 会创建一个新数组,将我们处理好的 map 数据结构的数据转换为数组形式
const result2 = Object.getOwnPropertyNames(map_data).map((v) => ({
    
    id: v, children: map_data[v]}))
console.log('result2 ==', result2)

至于执行的时间,可以看下面我的实际运行时间截图,可以明显发现 map 方法大幅度优化了代码的执行速度。
运行时长

猜你喜欢

转载自blog.csdn.net/qq_44886882/article/details/128722987