Skip to content

Latest commit

 

History

History
73 lines (47 loc) · 3.01 KB

baseSortedUniq.md

File metadata and controls

73 lines (47 loc) · 3.01 KB

lodash源码分析之baseSortedUniq

本文为读 lodash 源码的第八十八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

依赖

import eq from '../eq.js'

《lodash源码分析之NaN不是NaN》

源码分析

baseSortedUniq 是用来实现 sortedUniqsortedUniqBy 的内部方法,它的作用和 uniq 函数的作用差不多,传入一个数组 array ,然后返回这个数组去重后的结果。

但是 baseSortedUniquniq 不同的是,baseSortedUniq 只接受已经排好序的数组。

因为传入的数组是已经排好序的了,因此对数组进行迭代遍历时,只需要将前一个值保存起来,和当前值比较,如果和当前值不同,那这个值肯定是没有在这之前出现过的,就可以将这个值放入到结果集里了,如果相同,那肯定是出现过了,而且已经放过结果集里了,在这次迭代中不能再放到结果集里了。

来看源码:

function baseSortedUniq(array, iteratee) {
  let seen
  let index = -1
  let resIndex = 0

  const { length } = array
  const result = []

  while (++index < length) {
    const value = array[index], computed = iteratee ? iteratee(value) : value
    if (!index || !eq(computed, seen)) {
      seen = computed
      result[resIndex++] = value === 0 ? 0 : value
    }
  }
  return result
}

这里用 seen 来保存上次出现的不重复值。用 index 来作为迭代的指针,用 resIndex 作为结果数组的指针。

因为 baseSortedUniq 要支持 baseSortedBy,因此也支持传入 iteratee 来返回一个新值,再使用 iteratee 函数返回的值来作比较。

if (!index || !eq(computed, seen))

可以看到,这是符合条件的判断式,!index 是指 index0 的情况,也即数组的第一个值,因为数组的第一个值,也即肯定没有在之前出现过,所以要在结果集中。

如果不是第一个值,则调用 eq 来判断两个值是否相等,如果不相等,表示之前还没有出现过,要存入结果集中。

在存入结果集中之前,也将当前值保存在 seen 中,方便下一个值来比较。

注意到,在将 value 保存到结果集之前,有这样的判断:

value === 0 ? 0 : value

因为 javascript+0-00 ,即 0 也是带符号的,但是值都为 0 。在返回的结果中,统一作为 0 来处理。

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

作者:对角另一面