baseIntersection.js 1.9 KB
Newer Older
1 2 3 4 5
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';
徐立's avatar
徐立 committed
6 7 8 9 10 11 12 13 14 15 16 17

/**
 * The base implementation of methods like `intersection` that accepts an
 * array of arrays to inspect.
 *
 * @private
 * @param {Array} arrays The arrays to inspect.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new array of shared values.
 */
function baseIntersection(arrays, iteratee, comparator) {
18 19 20 21 22
	const includes = comparator ? arrayIncludesWith : arrayIncludes;
	const length = arrays[0].length;
	const othLength = arrays.length;
	const caches = new Array(othLength);
	const result = [];
徐立's avatar
徐立 committed
23

24 25 26
	let array;
	let maxLength = Infinity;
	let othIndex = othLength;
徐立's avatar
徐立 committed
27

28 29 30 31 32 33 34 35 36 37 38 39
	while (othIndex--) {
		array = arrays[othIndex];
		if (othIndex && iteratee) {
			array = map(array, (value) => iteratee(value));
		}
		maxLength = Math.min(array.length, maxLength);
		caches[othIndex] =
			!comparator && (iteratee || (length >= 120 && array.length >= 120))
				? new SetCache(othIndex && array)
				: undefined;
	}
	array = arrays[0];
徐立's avatar
徐立 committed
40

41 42
	let index = -1;
	const seen = caches[0];
徐立's avatar
徐立 committed
43

44 45 46
	outer: while (++index < length && result.length < maxLength) {
		let value = array[index];
		const computed = iteratee ? iteratee(value) : value;
徐立's avatar
徐立 committed
47

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
		value = comparator || value !== 0 ? value : 0;
		if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
			othIndex = othLength;
			while (--othIndex) {
				const cache = caches[othIndex];
				if (
					!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))
				) {
					continue outer;
				}
			}
			if (seen) {
				seen.push(computed);
			}
			result.push(value);
		}
	}
	return result;
徐立's avatar
徐立 committed
66 67
}

68
export default baseIntersection;