Search Part I: Sample ngram index

Example ngram implementation

by soundjewel

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<div ng-controller="MyCtrl">
    <h2>Part 1: Constructing a Trigram Index</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 - 2, 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(ngrams.map(function(ngram) {
          return $scope.hash[ngram] || [];        
        }));
    };
    
    $scope.hash = computeNGrams(dictionary);
});

// Some Array Helper Methods
var flatten = function(arrays) {
    var returnArray = [];
    if (!arrays) return [];
    arrays.forEach(function(array) {
        array.forEach(function(item) {
            if (returnArray.indexOf(item) == -1) {
                returnArray.push(item);
            }
        });
    });
    return returnArray;
};

var dictionary = 'When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature\'s God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the...