_equalArrays.js
 1  var SetCache = require('./_SetCache'),
 2      arraySome = require('./_arraySome'),
 3      cacheHas = require('./_cacheHas');
 4  
 5  /** Used to compose bitmasks for value comparisons. */
 6  var COMPARE_PARTIAL_FLAG = 1,
 7      COMPARE_UNORDERED_FLAG = 2;
 8  
 9  /**
10   * A specialized version of `baseIsEqualDeep` for arrays with support for
11   * partial deep comparisons.
12   *
13   * @private
14   * @param {Array} array The array to compare.
15   * @param {Array} other The other array to compare.
16   * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
17   * @param {Function} customizer The function to customize comparisons.
18   * @param {Function} equalFunc The function to determine equivalents of values.
19   * @param {Object} stack Tracks traversed `array` and `other` objects.
20   * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
21   */
22  function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
23    var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
24        arrLength = array.length,
25        othLength = other.length;
26  
27    if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
28      return false;
29    }
30    // Check that cyclic values are equal.
31    var arrStacked = stack.get(array);
32    var othStacked = stack.get(other);
33    if (arrStacked && othStacked) {
34      return arrStacked == other && othStacked == array;
35    }
36    var index = -1,
37        result = true,
38        seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
39  
40    stack.set(array, other);
41    stack.set(other, array);
42  
43    // Ignore non-index properties.
44    while (++index < arrLength) {
45      var arrValue = array[index],
46          othValue = other[index];
47  
48      if (customizer) {
49        var compared = isPartial
50          ? customizer(othValue, arrValue, index, other, array, stack)
51          : customizer(arrValue, othValue, index, array, other, stack);
52      }
53      if (compared !== undefined) {
54        if (compared) {
55          continue;
56        }
57        result = false;
58        break;
59      }
60      // Recursively compare arrays (susceptible to call stack limits).
61      if (seen) {
62        if (!arraySome(other, function(othValue, othIndex) {
63              if (!cacheHas(seen, othIndex) &&
64                  (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
65                return seen.push(othIndex);
66              }
67            })) {
68          result = false;
69          break;
70        }
71      } else if (!(
72            arrValue === othValue ||
73              equalFunc(arrValue, othValue, bitmask, customizer, stack)
74          )) {
75        result = false;
76        break;
77      }
78    }
79    stack['delete'](array);
80    stack['delete'](other);
81    return result;
82  }
83  
84  module.exports = equalArrays;