每日源码分析-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 復(fù)制代碼可以看到完完全全是調(diào)用baseUniq函數(shù),如果這樣就完的話感覺今天就比較水,所以我們來看看這個(gè)baseUniq函數(shù)
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 復(fù)制代碼由于這個(gè)函數(shù)還考慮了對(duì)數(shù)據(jù)的'處理器'和'比較器',如果有興趣的話可以再仔細(xì)看看整體的實(shí)現(xiàn),今天我們就只看uniq函數(shù)調(diào)用時(shí)的情況(既沒有'處理器'也沒有'比較器')。我做了個(gè)簡化,代碼如下:
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 } 復(fù)制代碼這樣一來就很明確了。如果數(shù)組長度大于200(LARGE_ARRAY_SIZE),則使用cache那套來判斷cache里有沒有對(duì)應(yīng)的數(shù)據(jù),沒有就添加進(jìn)cache和結(jié)果數(shù)組。如果是普通的長度小于200的數(shù)組,那么就和我們平時(shí)寫的差不多了:遍歷獲取目標(biāo)數(shù)組的值并且遍歷查詢結(jié)果數(shù)組判斷該值是否已經(jīng)存在,不存在存入結(jié)果數(shù)組。
使用方式
_.uniq([2, 1, 2])// => [2, 1] 復(fù)制代碼使用場景
該函數(shù)作用是將一個(gè)數(shù)組去重,由于內(nèi)部判斷相等機(jī)制是采用===,所以只能滿足我們常見的判斷簡單的數(shù)組相同,類似于[[2],[2]]等hash值不同的對(duì)象不能去重。
let t = [2]_.uniq([2, 1, 2, t, t])// => [2, 1, [2]] 復(fù)制代碼結(jié)語
個(gè)人感覺如果要簡單的進(jìn)行類似的去重可以使用es6的set直接達(dá)到目的:Array.from(new Set(yourArray))或者[...new Set(yourArray)]就可以了。如果要對(duì)內(nèi)容去重則需要進(jìn)行遞歸操作。
補(bǔ)充?其實(shí)還可以使用正則來去重。比如
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"]復(fù)制代碼總結(jié)
以上是生活随笔為你收集整理的每日源码分析-Lodash(uniq.js)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android NDK开发之旅34 N
- 下一篇: JavaScript 编码小技巧