_.union([arrays])


49

_.union([arrays])
_.union接收多個數組為參數,創建一個去重后的數組,使用SameValueZero規則來比較元素是否相等

參數

[arrays] (...Array): 需要處理的多個數組

返回值

(Array): 返回連起來的去重后的數組

例子

_.union([2], [1, 2]);
// => [2, 1]

源代碼:

大數組的緩存機制之前看過了,省略

import baseFlatten from './.internal/baseFlatten.js'
import baseUniq from './.internal/baseUniq.js'
import isArrayLikeObject from './isArrayLikeObject.js'

/**
 * Creates an array of unique values, in order, from all given arrays using
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons.
 *
 * @since 0.1.0
 * @category Array
 * @param {...Array} [arrays] The arrays to inspect.
 * @returns {Array} Returns the new array of combined values.
 * @see difference, unionBy, unionWith, without, xor, xorBy
 * @example
 *
 * union([2, 3], [1, 2])
 * // => [2, 3, 1]
 */
//接收多個數組為參數,創建一個去重后的數組,使用SameValueZero規則來比較元素是否相等
function union(...arrays) {
  return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true))
  //將參數數組展開一層后形成的數組傳遞給baseUniq處理
}

export default union

baseUniq

import SetCache from './SetCache.js'
import arrayIncludes from './arrayIncludes.js'//判斷數組是否包含給定值
import arrayIncludesWith from './arrayIncludesWith.js'//判斷數組是否包含給定值,區別是它的comparator需要作為參數傳入
import cacheHas from './cacheHas.js'
import createSet from './createSet.js'
import setToArray from './setToArray.js'

/** Used as the size to enable large array optimizations. */
const LARGE_ARRAY_SIZE = 200

/**
 * The base implementation of `uniqBy`.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new duplicate free array.
 */
//uniqBy的基礎實現,數組去重
function baseUniq(array, iteratee, comparator) {
  let index = -1//循環索引
  let includes = arrayIncludes//類似數組的includes方法,判斷數組是否包含給定值
  let isCommon = true//有沒有自定義比較器或者有沒有開啟緩存的標記

  const { length } = array//數組長度
  const result = []//結果數組
  let seen = result//臨時數組,用來存入不重復的數組元素值

  if (comparator) {//如果傳遞了自定義比較器,incledes方法就用arrayIncludesWith
    isCommon = false
    includes = arrayIncludesWith
  }
  else if (length >= LARGE_ARRAY_SIZE) {//如果數組長度超過200,就設置緩存
    const set = iteratee ? null : createSet(array)//如果沒有iteratee和comparator,就直接使用ES6的set類型去重
    if (set) {//如果可以用set類型去重,直接新建set對象然后再轉換成數組后返回結果
      return setToArray(set)
    }
    isCommon = false//否則開啟數組緩存
    includes = cacheHas
    seen = new SetCache
  }
  else {//如果沒有自定義比較器,數組長度也沒有超過200
    seen = iteratee ? [] : result
  }
  outer:
  while (++index < length) {//遍歷數組
    let value = array[index]//當前元素
    const computed = iteratee ? iteratee(value) : value//iteratee處理后的當前元素

    value = (comparator || value !== 0) ? value : 0//如果沒有傳遞comparator,將-0變為0
    if (isCommon && computed === computed) {//如果沒有傳遞自定義比較器,或者沒有開啟緩存,並且computed不是NaN
      let seenIndex = seen.length//seen數組的長度
      while (seenIndex--) {//遍歷seen數組,如果有和當前值一樣的,就跳出本次循環直接進行下一次
        if (seen[seenIndex] === computed) {
          continue outer
        }
      }
      if (iteratee) {//如果有iteratee參數,seen結尾插入當前不重復的元素
        seen.push(computed)
      }
      result.push(value)//結果數組結尾插入當前不重復的元素
    }
    else if (!includes(seen, computed, comparator)) {//如果有自定義比較器或者開啟了緩存,並且seen中沒有當前元素
      if (seen !== result) {//開啟緩存的情況seen數組要插入新值
        seen.push(computed)
      }
      result.push(value)//結果數組插入新值
    }
  }
  return result
}

export default baseUniq

createSet

import setToArray from './setToArray.js'

/** Used as references for various `Number` constants. */
const INFINITY = 1 / 0

/**
 * Creates a set object of `values`.
 *
 * @private
 * @param {Array} values The values to add to the set.
 * @returns {Object} Returns the new set.
 */
//根據給定數組創建set對象
const createSet = (Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY)
  ? (values) => new Set(values)
  : () => {}
  //如果有Set類型,並且Set初始化時空白位置會賦值為undefined不會跳過,就返回新實例化Set對象的一個方法
  //否則返回一個什么都不做的方法

export default createSet

setToArray

/**
 * Converts `set` to an array of its values.
 *
 * @private
 * @param {Object} set The set to convert.
 * @returns {Array} Returns the values.
 */
//將一個set對象轉換為一個數組
function setToArray(set) {
  let index = -1//循環索引
  const result = new Array(set.size)//結果數組

  set.forEach((value) => {//遍歷set賦值給結果數組
    result[++index] = value
  })
  return result
}

export default setToArray

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM