成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

lodash源碼分析之?dāng)?shù)組的差集

Noodles / 2696人閱讀

摘要:依賴源碼分析之緩存使用方式的進(jìn)一步封裝源碼分析之源碼分析之源碼分析之的實(shí)現(xiàn)源碼分析之源碼分析的調(diào)用如果有傳遞,則先調(diào)用,使用生成要比較數(shù)組的映射數(shù)組。循環(huán)完畢,沒(méi)有在第二個(gè)數(shù)組中發(fā)現(xiàn)相同的項(xiàng)時(shí),將該項(xiàng)存入數(shù)組中。

外部世界那些破舊與貧困的樣子,可以使我內(nèi)心世界得到平衡。

——卡爾維諾《煙云》

本文為讀 lodash 源碼的第十七篇,后續(xù)文章會(huì)更新到這個(gè)倉(cāng)庫(kù)中,歡迎 star:pocket-lodash

gitbook也會(huì)同步倉(cāng)庫(kù)的更新,gitbook地址:pocket-lodash

作用與用法

baseDifference 可以用來(lái)獲取指定數(shù)組與另一個(gè)數(shù)組的差集。

這個(gè)函數(shù)是內(nèi)部函數(shù),是后面實(shí)現(xiàn)其它比較函數(shù)的核心函數(shù)。

baseDifference 的方法簽名如下:

baseDifference(array, values, iteratee, comparator)

第一和第二個(gè)參數(shù)是需要比較的兩個(gè)數(shù)組;iteratee 可以返回一值映射值,比較時(shí),可以使用映射的值來(lái)進(jìn)行比較; comparator 是自定義比較函數(shù),如果有傳遞,則調(diào)用自定義的比較函數(shù)來(lái)進(jìn)行交集的比較。

依賴
import SetCache from "./SetCache.js"
import arrayIncludes from "./arrayIncludes.js"
import arrayIncludesWith from "./arrayIncludesWith.js"
import map from "../map.js"
import cacheHas from "./cacheHas.js"

lodash源碼分析之緩存使用方式的進(jìn)一步封裝

lodash源碼分析之a(chǎn)rrayIncludes

lodash源碼分析之a(chǎn)rrayIncludesWith

lodash源碼分析之map的實(shí)現(xiàn)

lodash源碼分析之cacheHas

源碼分析
const LARGE_ARRAY_SIZE = 200
function baseDifference(array, values, iteratee, comparator) {
  let includes = arrayIncludes
  let isCommon = true
  const result = []
  const valuesLength = values.length

  if (!array.length) {
    return result
  }
  if (iteratee) {
    values = map(values, (value) => iteratee(value))
  }
  if (comparator) {
    includes = arrayIncludesWith
    isCommon = false
  }
  else if (values.length >= LARGE_ARRAY_SIZE) {
    includes = cacheHas
    isCommon = false
    values = new SetCache(values)
  }
  outer:
  for (let value of array) {
    const computed = iteratee == null ? value : iteratee(value)

    value = (comparator || value !== 0) ? value : 0
    if (isCommon && computed === computed) {
      let valuesIndex = valuesLength
      while (valuesIndex--) {
        if (values[valuesIndex] === computed) {
          continue outer
        }
      }
      result.push(value)
    }
    else if (!includes(values, computed, comparator)) {
      result.push(value)
    }
  }
  return result
}
iteratee的調(diào)用
if (iteratee) {
  values = map(values, (value) => iteratee(value))
}

如果有傳遞 iteratee ,則先調(diào)用 map ,使用 iteratee 生成要比較數(shù)組的映射數(shù)組 values。

因?yàn)楹竺鏁?huì)有嵌套循環(huán),避免重復(fù)調(diào)用 iteratee ,影響性能,所以一開(kāi)始就需要生成 values 的映射數(shù)組。

性能優(yōu)化

這里使用了 isCommon 來(lái)標(biāo)志是否使用普通方式來(lái)處理。

if (comparator) {
  includes = arrayIncludesWith
  isCommon = false
}

如果有傳遞比較函數(shù),則將 isCommon 標(biāo)記為 false,表示不用普通的方式來(lái)處理,后面可以看到,最后會(huì)使用 includes 方法來(lái)處理,也即 arrayIncludesWith 方法。

else if (values.length >= LARGE_ARRAY_SIZE) {
  includes = cacheHas
  isCommon = false
  values = new SetCache(values)
}

如果不需要使用自定義的比較方式,并且數(shù)組較大時(shí)(這里限定了200),則使用 SetCache 類(lèi)來(lái)緩存數(shù)組。

SetChche 其實(shí)使用的是 Map/Set 或者對(duì)象的方式來(lái)存儲(chǔ),避免大數(shù)組嵌套循環(huán)時(shí)造成的性能損耗。

### 循環(huán)比較

接下來(lái)就遍歷第一個(gè)數(shù)組 array,將數(shù)組中的每一項(xiàng)和第二個(gè)數(shù)組的每一項(xiàng)比較。

if (isCommon && computed === computed) {
  let valuesIndex = valuesLength
  while (valuesIndex--) {
    if (values[valuesIndex] === computed) {
      continue outer
    }
  }
  result.push(value)
}
else if (!includes(values, computed, comparator)) {
  result.push(value)
}

可以看到,如果 isCommon 沒(méi)有標(biāo)記為 false, 或者需要比較的值 computed 不為 NaN 時(shí),都采用嵌套循環(huán)的方式來(lái)比較。循環(huán)完畢,沒(méi)有在第二個(gè)數(shù)組中發(fā)現(xiàn)相同的項(xiàng)時(shí),將該項(xiàng)存入數(shù)組 result 中。

如果 isCommonfalse 或者需要比較的值為 NaN 時(shí),則調(diào)用 includes 方法來(lái)比較。

由之前的分析得知:

如果指定 comparator ,則 includesarrayIncludesWith

如果被比較的數(shù)組 values 的長(zhǎng)度超過(guò) 200 ,則 includescacheHas

否則,includesarrayIncludes

+0與-0的處理

在看代碼的時(shí)候,有一段十分奇怪:

value = (comparator || value !== 0) ? value : 0

這段代碼的意思是,在沒(méi)有提供 comparator 的情況下,如果 value === 0 ,則將 value 賦值為 0 。

value === 0 時(shí),可能為 +0 、-00 ,lodash 為什么要將它們都轉(zhuǎn)為 0 呢?

后來(lái)看到 lodash 作者在 issue 中說(shuō),因?yàn)楸容^會(huì)用到 Set ,而 Set 是不能區(qū)分 +0-0 的。

參考

Lodash系列——difference函數(shù)源碼解析

value = (comparator || value !== 0) ? value : 0; does it work?

License

署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際 (CC BY-NC-ND 4.0)

最后,所有文章都會(huì)同步發(fā)送到微信公眾號(hào)上,歡迎關(guān)注,歡迎提意見(jiàn):

作者:對(duì)角另一面

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93421.html

相關(guān)文章

  • lodash源碼分析緩存使用方式進(jìn)一步封裝

    摘要:但是在類(lèi)中,要初始化緩存和設(shè)置緩存都需要提供和組成的二維數(shù)組,因此在類(lèi)中,提供了一種更方便的緩存設(shè)置方式,只需要提供緩存的值即可。這里構(gòu)造函數(shù)不需要再傳入的二維數(shù)組了,只需要傳入包含所有緩存值的數(shù)組即可。 在世界上所有的民族之中,支配著他們的喜怒選擇的并不是天性,而是他們的觀點(diǎn)。——盧梭《社會(huì)與契約論》 本文為讀 lodash 源碼的第九篇,后續(xù)文章會(huì)更新到這個(gè)倉(cāng)庫(kù)中,歡迎 star...

    neroneroffy 評(píng)論0 收藏0
  • lodash源碼分析緩存使用方式進(jìn)一步封裝

    摘要:但是在類(lèi)中,要初始化緩存和設(shè)置緩存都需要提供和組成的二維數(shù)組,因此在類(lèi)中,提供了一種更方便的緩存設(shè)置方式,只需要提供緩存的值即可。這里構(gòu)造函數(shù)不需要再傳入的二維數(shù)組了,只需要傳入包含所有緩存值的數(shù)組即可。 在世界上所有的民族之中,支配著他們的喜怒選擇的并不是天性,而是他們的觀點(diǎn)?!R梭《社會(huì)與契約論》 本文為讀 lodash 源碼的第九篇,后續(xù)文章會(huì)更新到這個(gè)倉(cāng)庫(kù)中,歡迎 star...

    wapeyang 評(píng)論0 收藏0
  • lodash源碼分析chunk尺與刀

    摘要:萬(wàn)條數(shù)據(jù)依賴讀源碼之從看稀疏數(shù)組與密集數(shù)組原理的原理歸結(jié)起來(lái)就是切割和放置。尺在切割之前,需要用尺確定切割的數(shù)量。容器的長(zhǎng)度剛好與塊的數(shù)量一致。當(dāng)與塊的數(shù)量相等時(shí),表示已經(jīng)切割完畢,停止切割,最后將結(jié)果返回。 以不正義開(kāi)始的事情,必須用罪惡使它鞏固?!勘葋啞尔溈税住? 最近很多事似乎印證了這句話,一句謊言最后要用一百句謊言來(lái)圓謊。 本文為讀 lodash 源碼的第二篇,后續(xù)文章會(huì)...

    ZweiZhao 評(píng)論0 收藏0
  • lodash源碼分析自減兩種形式

    摘要:作用與用法是的內(nèi)部函數(shù),之前在源碼分析之緩存介紹過(guò)一種這樣的數(shù)據(jù)結(jié)構(gòu)這是一個(gè)二維數(shù)組,每項(xiàng)中的第一項(xiàng)作為緩存對(duì)象的,第二項(xiàng)為緩存的值。 這個(gè)世界需要一個(gè)特定的惡人,可以供人們指名道姓,千夫所指:全都怪你?!迳洗簶?shù)《當(dāng)我談跑步時(shí)我談些什么》 本文為讀 lodash 源碼的第六篇,后續(xù)文章會(huì)更新到這個(gè)倉(cāng)庫(kù)中,歡迎 star:pocket-lodash gitbook也會(huì)同步倉(cāng)庫(kù)的更新...

    Keven 評(píng)論0 收藏0
  • lodash源碼分析List緩存

    摘要:在之前的文章中已經(jīng)介紹過(guò),檢測(cè)的是對(duì)應(yīng)的數(shù)組在二維數(shù)組中的索引,其行為跟一致,不存在于二維數(shù)組中時(shí),返回,否則返回索引值。最后將緩存數(shù)量減少。 昨日我沿著河岸/漫步到/蘆葦彎腰喝水的地方順便請(qǐng)煙囪/在天空為我寫(xiě)一封長(zhǎng)長(zhǎng)的信 潦是潦草了些/而我的心意/則明亮亦如你窗前的燭光/稍有曖昧之處/勢(shì)所難免/因?yàn)轱L(fēng)的緣故 ——洛夫《因?yàn)轱L(fēng)的緣故》 本文為讀 lodash 源碼的第七篇,后續(xù)文章會(huì)...

    leon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<