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...