Search Part II: Exact Pattern Matching

http://angularjs.org/

by rocketegg0

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<div ng-controller="MyCtrl">
    <h2>Part 2: Exact Pattern Matching</h2>
    <input type="text" ng-model="textIn"></input>
    <div>
        Typeahead Results: 
        <ul>
            <li ng-repeat="word in typeahead(textIn)">{{word}}</li>
        </ul>
    </div>
</div>

CSS

h2 {
    font-size: 150%;
}

JavaScript

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function($scope, $q) {
    
    // Compute NGrams
    var computeNGrams = function(dict) {     
        return dict.split(' ').reduce(function(hash, word) {
            return ngramize(hash, word);
        }, {});
    };
    
    // NGramize a word
    function ngramize(hash, word) {
        for (var i = 3; i < word.length+1; i++) {
            var s = word.substring(i - 3, i);
            if (!hash.hasOwnProperty(s)) {
                hash[s] = [word]
            } else {
                if (hash[s].indexOf(word) == -1) {
                    hash[s].push(word)
                }
            }
        }
        return hash;
    }
    
    $scope.typeahead = function(textIn) {
        if (!textIn || textIn.length < 3) return [];
        var ngrams = Object.keys(ngramize({}, textIn));
        return flatten(merge(ngrams.map(function(ngram) {
          return $scope.hash[ngram] || [];        
        })));
    };
    
    var merge = function(arrays) {
        var returnArray = [];
        if (!arrays) return [];
        var matches = {};
        arrays.forEach(function(array) {
            array.reduce(function(matches, word) {
                if (!matches.hasOwnProperty(word)) {
                    matches[word] = 1;
                } else {
                    matches[word] += 1;
                }
                return matches;
            }, matches);
        });
        
        //If the word intersects all arrays
        returnArray = select(Object.keys(matches), function(word) {
            return matches[word] === arrays.length;
        });
        return returnArray;
    };
    
    $scope.hash = computeNGrams(dictionary);
});

// Some Array Helper Methods
var flatten = function(arrays) {
    var returnArray = [];
    if (!arrays) return [];
    arrays.forEach(function(array) {
        if (angular.isArray(array)) {
            array.forEach(function(item) {
                if...