Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lodash源码分析之baseXor #111

Open
HeftyKoo opened this issue Mar 7, 2020 · 0 comments
Open

lodash源码分析之baseXor #111

HeftyKoo opened this issue Mar 7, 2020 · 0 comments
Labels
internal 内部函数或方法 系列文章

Comments

@HeftyKoo
Copy link
Owner

HeftyKoo commented Mar 7, 2020

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

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

依赖

import baseDifference from './baseDifference.js'
import baseFlatten from './baseFlatten.js'
import baseUniq from './baseUniq.js'

《lodash源码分析之数组的差集》
《lodash源码分析之baseFlatten》
《lodash源码分析之baseUniq》

源码分析

baseXor 的作用是,传入一个数组集 arrays ,找出这个数组集中,只在其中一个数组中存在的元素,组成新的数组作为结果返回。

baseXor 和其他很多 base 类的内部函数一样,也支持迭代器 iterateecomparator

例如:

baseXor([1,2, 4],[2, 3], [3, 4]) // => [1] 

源码如下:

function baseXor(arrays, iteratee, comparator) {
  const length = arrays.length
  if (length < 2) {
    return length ? baseUniq(arrays[0]) : []
  }
  let index = -1
  const result = new Array(length)

  while (++index < length) {
    const array = arrays[index]
    let othIndex = -1

    while (++othIndex < length) {
      if (othIndex != index) {
        result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator)
      }
    }
  }
  return baseUniq(baseFlatten(result, 1), iteratee, comparator)
}

如果传入的 arrayslength0 ,则返回空数组即可。

如果传入一个数组,则使用 baseUniq 去重即可。

对应的代码如下:

const length = arrays.length
if (length < 2) {
  return length ? baseUniq(arrays[0]) : []
}

即如果有多个数组,要怎样去找只出现在其中一个数组中的元素呢?

我们可以先找出第一个数组中,所有只出现在第一个数组中的元素,再找出第二个数组中,所有只出现在这个数组中的元素,依此类推,最后将所有这些元素合并在一起,再进行去重就可以啦。

那怎样去找所有只出现在第一个数组中的元素呢?

我们只需要找出第一个数组和第二个数组的差集,假设存在数组 result[0] 中,然后再找出 result[0] 和第三个数组的差集,得出的结果重新存入 result[0],依此类推,最后得出的结果肯定是只出现在第一个数组中的所有元素。

具体的代码如下:

let index = -1
const result = new Array(length)

while (++index < length) {
  const array = arrays[index]
  let othIndex = -1

  while (++othIndex < length) {
    if (othIndex != index) {
      result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator)
    }
  }
}

得出的 resultarrays 的长度一致。

因为 result 中每个元素都是数组,可以使用 baseFlatten(result, 1)result 展平,然后再调用 baseUniq 去重,即可得出最终的结果。

License

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

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

作者:对角另一面

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal 内部函数或方法 系列文章
Projects
None yet
Development

No branches or pull requests

1 participant