intersect method

TokenSet intersect(
  1. TokenSet b
)

Returns a new TokenSet that is the intersection of this TokenSet and the passed TokenSet.

This intersection will take into account any wildcards contained within the TokenSet.

@param {lunr.TokenSet} b - An other TokenSet to intersect with. @returns {lunr.TokenSet}

Implementation

TokenSet intersect(TokenSet b) {
  var output = TokenSet();
  Frame? frame;

  var stack = [Frame(qNode: b, output: output, node: this)];

  while (stack.isNotEmpty) {
    frame = stack.removeLast();

    // NOTE: As with the #toString method, we are using
    // Object.keys and a for loop instead of a for-in loop
    // as both of these objects enter 'hash' mode, causing
    // the function to be de-optimised in V8
    List<String> qEdges = frame.qNode!.edges.keys.toList();
    int qLen = qEdges.length;
    List<String> nEdges = frame.node.edges.keys.toList();
    int nLen = nEdges.length;

    for (var q = 0; q < qLen; q++) {
      var qEdge = qEdges[q];

      for (var n = 0; n < nLen; n++) {
        var nEdge = nEdges[n];

        if (nEdge == qEdge || qEdge == '*') {
          TokenSet node = frame.node.edges[nEdge]!;
          TokenSet qNode = frame.qNode!.edges[qEdge]!;
          bool isFinal = node.isFinal && qNode.isFinal;
          TokenSet? next;

          if (frame.output!.edges.containsKey(nEdge)) {
            // an edge already exists for this character
            // no need to create a new node, just set the finality
            // bit unless this node is already final
            next = frame.output!.edges[nEdge]!;
            next.isFinal = next.isFinal || isFinal;
          } else {
            // no edge exists yet, must create one
            // set the finality bit and insert it
            // into the output
            next = TokenSet();
            next.isFinal = isFinal;
            frame.output!.edges[nEdge] = next;
          }

          stack.add(Frame(qNode: qNode, output: next, node: node));
        }
      }
    }
  }
  return output;
}