fe-notes icon indicating copy to clipboard operation
fe-notes copied to clipboard

对象数组去重

Open Inchill opened this issue 3 years ago • 0 comments

有一个未知的对象数组,数组的每一项存储的都是对象,现在需要对这个数组去重。这个和我们常见的对象数组不太一样,以往我们会根据对象数组里对象的某些属性去重,而这道题我们无法得知对象里的属性是什么,所以需要采取最直观的方式去重。

function dropDuplicate (arr = []) {
  if (arr.length <= 1) return arr

  const isSameObj = (a = {}, b = {}) => {
    if (typeof a !== 'object' || typeof b !== 'object') return false

    if (Object.keys(a).length !== Object.keys(b).length) return false

    for (const [key, value] of Object.entries(a)) {
      if (typeof value === 'object' || typeof b[key] === 'object') {
        return isSameObj(value, b[key])
      }
      if (!b[key] || b[key] !== value) return false
    }

    return true
  }

  let dropIdx = []
  for (var i = 0, len = arr.length; i < len - 1; i++) {
    for (var j = i + 1; j < len; j++) {
      if (isSameObj(arr[i], arr[j])) dropIdx.push(j)
    }
  }

  dropIdx.forEach(index => arr.splice(index, 1, null))

  return arr.filter(item => item !== null)
}

let objArr = [
  {
    name: 'chuck',
    gender: 'male',
    children: {
      name: 'nick',
      bro: []
    }
  },
  {
    name: 'chuck',
    gender: 'male',
    children: {
      name: 'nick',
      bro: []
    }
  },
  {
    name: 'henry',
    gender: 'male'
  },
  {
    name: 'mary',
    gender: 'female'
  },
  {
    name: 'mary',
    gender: 'female'
  }
]

console.log(dropDuplicate(objArr))
// 输出如下
// [
//   {
//     name: 'chuck',
//     gender: 'male',
//     children: { name: 'nick', bro: [] }
//   },
//   { name: 'henry', gender: 'male' },
//   { name: 'mary', gender: 'female' }
// ]

我只想到了这种时间复杂度为 O(n * n) 的解法,如果看到的同学有 O(n) 的方案,欢迎补充。

Inchill avatar Oct 20 '22 07:10 Inchill