11种前端数据去重方式你都知道吗?

74 阅读2分钟

本文总结了JavaScript去重的多种方式,各有优缺点,根据需求合理使用吧。

  • 使用 for 循环和 indexOf 方法,复杂度 O(n^2)
function uniqueArray(arr) {
  const result = []
    for (let i = 0; i < arr.length; i++) {
        if (result.indexOf(arr[i]) === -1) {
              result.push(arr[i])
                  }
                    }
                      return result
                      }
  • 使用 for 循环和对象,复杂度 O(n^2)
function uniqueArray(arr) {
  const result = []
    const obj = {}
      for (let i = 0; i < arr.length; i++) {
          if (!obj[arr[i]]) {
                result.push(arr[i])
                      obj[arr[i]] = true
                          }
                            }
                              return result
                              }
  • 使用 filter 方法和 indexOf 方法,复杂度 O(n^2)
function uniqueArray(arr) {
  return arr.filter((item, index, arr) => arr.indexOf(item) === index)
  }
  • 使用 filter 方法和对象,复杂度 O(n)
function uniqueArray(arr) {
  const obj = {}
    return arr.filter((item) => obj.hasOwnProperty(item) ? false : (obj[item] = true))
    }
  • 使用 Set 数据结构,复杂度 O(n)
                    // 使用解构 + Set
                    function uniqueArray(arr) {
                      return [...new Set(arr)]
                      }" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
function uniqueArray(arr) {
  return Array.from(new Set(arr))
  }

// 使用解构 + Set function uniqueArray(arr) { return [...new Set(arr)] }

  • 使用 Map 数据结构,复杂度 O(n)
<button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function uniqueArray(arr) { const map = new Map(); const result = []; for (let i = 0; i < arr.length; i++) { if (!map.has(arr[i])) { map.set(arr[i], true); result.push(arr[i]); } } return result; }

                                                // or
                                                function uniqueArray(arr) {
                                                  const map = new Map();
                                                    return arr.filter(function(item) {
                                                        return !map.has(item) &amp;&amp; map.set(item, true);
                                                          });
                                                          }" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
function uniqueArray(arr) {
  const map = new Map();
    const result = [];
      for (let i = 0; i < arr.length; i++) {
          if (!map.has(arr[i])) {
                map.set(arr[i], true);
                      result.push(arr[i]);
                          }
                            }
                              return result;
                              }
                          <span class="hljs-comment">// or</span>
                          <span class="hljs-keyword">function</span> <span class="hljs-title function_">uniqueArray</span>(<span class="hljs-params">arr</span>) {
                            <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Map</span>();
                              <span class="hljs-keyword">return</span> arr.<span class="hljs-title function_">filter</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">item</span>) {
                                  <span class="hljs-keyword">return</span> !map.<span class="hljs-title function_">has</span>(item) &amp;&amp; map.<span class="hljs-title function_">set</span>(item, <span class="hljs-literal">true</span>);
                                    });
                                    }</pre><ul><li>使用双重循环和 <code>splice</code> 方法,复杂度 O(n^2)</li></ul><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function uniqueArray(arr) {
                    for (var i = 0; i < arr.length; i++) {
                        for (var j = i + 1; j < arr.length; j++) {
                              if (arr[i] === arr[j]) {
                                      arr.splice(j, 1);
                                              j--;
                                                    }
                                                        }
                                                          }
                                                            return arr;
                                                            }" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
function uniqueArray(arr) {
  for (var i = 0; i < arr.length; i++) {
      for (var j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) {
                    arr.splice(j, 1);
                            j--;
                                  }
                                      }
                                        }
                                          return arr;
                                          }
  • 使用排序和双指针

使用排序和双指针可以实现 O(nlogn) 的时间复杂度。先对数组进行排序,然后使用双指针遍历数组,如果左指针和右指针指向的值相同,就把右指针向右移动,直到找到不同的值,然后把左指针向右移动,继续遍历。

function uniqueArray(arr) {
  arr.sort();
    var left = 0, right = 1;
      var result = [];
        while (right <= arr.length) {
            if (arr[left] === arr[right]) {
                  right++;
                      } else {
                            result.push(arr[left]);
                                  left = right;
                                        right++;
                                            }
                                              }
                                                return result;
                                                }
  • 使用 reduce 方法和 includes,复杂度 O(n^2)
function uniqueArray(arr) {
  return arr.reduce(function(prev, cur) {
      if (!prev.includes(cur)) {
            prev.push(cur);
                }
                    return prev;
                      }, []);
                      }
  • 使用递归和 includes,复杂度 O(n^2)
function uniqueArray(arr) {
  if (arr.length === 1) {
      return arr;
        } else {
            const first = arr[0];
                const rest = uniqueArray(arr.slice(1));
                    if (rest.includes(first)) {
                          return rest;
                              } else {
                                    return [first].concat(rest);
                                        }
                                          }
                                          }
  • 双层循环,复杂度 O(n^2)
function uniqueArray(arr) {
  var result = [];
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < result.length; j++) {
              if (arr[i] === result[j]) {
                      break;
                            }
                                }
                                    if (j === result.length) {
                                          result.push(arr[i]);
                                              }
                                                }
                                                  return result;
                                                  }