每日源码分析-Lodash(uniq.js)
生活随笔
收集整理的這篇文章主要介紹了
每日源码分析-Lodash(uniq.js)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本系列使用lodash 4.17.4
前言
引用internal文件下的baseUniq.js
正文
import baseUniq from './.internal/baseUniq.js'/*** Creates a duplicate-free version of an array, using* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)* for equality comparisons, in which only the first occurrence of each element* is kept. The order of result values is determined by the order they occur* in the array.** @since 0.1.0* @category Array* @param {Array} array The array to inspect.* @returns {Array} Returns the new duplicate free array.* @see uniqBy, uniqWith* @example** uniq([2, 1, 2])* // => [2, 1]*/ function uniq(array) {return (array != null && array.length)? baseUniq(array): [] }export default uniq 復制代碼可以看到完完全全是調用baseUniq函數,如果這樣就完的話感覺今天就比較水,所以我們來看看這個baseUniq函數
import SetCache from './SetCache.js' import arrayIncludes from './arrayIncludes.js' import arrayIncludesWith from './arrayIncludesWith.js' 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.*/ function baseUniq(array, iteratee, comparator) {let index = -1let includes = arrayIncludeslet isCommon = trueconst { length } = arrayconst result = []let seen = resultif (comparator) {isCommon = falseincludes = arrayIncludesWith}else if (length >= LARGE_ARRAY_SIZE) {const set = iteratee ? null : createSet(array)if (set) {return setToArray(set)}isCommon = falseincludes = cacheHasseen = new SetCache}else {seen = iteratee ? [] : result}outer:while (++index < length) {let value = array[index]const computed = iteratee ? iteratee(value) : valuevalue = (comparator || value !== 0) ? value : 0if (isCommon && computed === computed) {let seenIndex = seen.lengthwhile (seenIndex--) {if (seen[seenIndex] === computed) {continue outer}}if (iteratee) {seen.push(computed)}result.push(value)}else if (!includes(seen, computed, comparator)) {if (seen !== result) {seen.push(computed)}result.push(value)}}return result } export default baseUniq 復制代碼由于這個函數還考慮了對數據的'處理器'和'比較器',如果有興趣的話可以再仔細看看整體的實現,今天我們就只看uniq函數調用時的情況(既沒有'處理器'也沒有'比較器')。我做了個簡化,代碼如下:
import SetCache from './SetCache.js' import arrayIncludes from './arrayIncludes.js' import arrayIncludesWith from './arrayIncludesWith.js' 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 = 200function baseUniq(array) {let index = -1let includes = arrayIncludeslet isCommon = trueconst { length } = arrayconst result = []let seen = resultif (length >= LARGE_ARRAY_SIZE) {const set = createSet(array)if (set) {return setToArray(set)}isCommon = falseincludes = cacheHasseen = new SetCache}else {seen = result}outer:while (++index < length) {let value = array[index]value = value !== 0 ? value : 0if (isCommon) {let seenIndex = seen.lengthwhile (seenIndex--) {if (seen[seenIndex] === value) {continue outer}}result.push(value)}else if (!includes(seen, value)) {if (seen !== result) {seen.push(value)}result.push(value)}}return result } 復制代碼這樣一來就很明確了。如果數組長度大于200(LARGE_ARRAY_SIZE),則使用cache那套來判斷cache里有沒有對應的數據,沒有就添加進cache和結果數組。如果是普通的長度小于200的數組,那么就和我們平時寫的差不多了:遍歷獲取目標數組的值并且遍歷查詢結果數組判斷該值是否已經存在,不存在存入結果數組。
使用方式
_.uniq([2, 1, 2])// => [2, 1] 復制代碼使用場景
該函數作用是將一個數組去重,由于內部判斷相等機制是采用===,所以只能滿足我們常見的判斷簡單的數組相同,類似于[[2],[2]]等hash值不同的對象不能去重。
let t = [2]_.uniq([2, 1, 2, t, t])// => [2, 1, [2]] 復制代碼結語
個人感覺如果要簡單的進行類似的去重可以使用es6的set直接達到目的:Array.from(new Set(yourArray))或者[...new Set(yourArray)]就可以了。如果要對內容去重則需要進行遞歸操作。
補充?其實還可以使用正則來去重。比如
var str_arr = ["a", "b", "c", "a", "b", "c"]function unique(arr) {return arr.sort().join(",,"). replace(/(,|^)([^,]+)(,,\2)+(,|$)/g, "$1$2$4"). replace(/,,+/g, ",").replace(/,$/, "").split(",") } console.log(unique(str_arr)) // ["a","b","c"]復制代碼總結
以上是生活随笔為你收集整理的每日源码分析-Lodash(uniq.js)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android NDK开发之旅34 N
- 下一篇: JavaScript 编码小技巧