UNPKG

3.57 kBJavaScriptView Raw
1// MODIFIED BY NS/CJ - Don't extend the prototype of String
2// MODIFIED BY CJ - Remove start_of_string_bonus
3
4/*!
5 * string_score.js: String Scoring Algorithm 0.1.10
6 *
7 * http://joshaven.com/string_score
8 * https://github.com/joshaven/string_score
9 *
10 * Copyright (C) 2009-2011 Joshaven Potter <yourtech@gmail.com>
11 * Special thanks to all of the contributors listed here https://github.com/joshaven/string_score
12 * MIT license: http://www.opensource.org/licenses/mit-license.php
13 *
14 * Date: Tue Mar 1 2011
15*/
16
17/**
18 * Scores a string against another string.
19 * 'Hello World'.score('he'); //=> 0.5931818181818181
20 * 'Hello World'.score('Hello'); //=> 0.7318181818181818
21 */
22module.exports = function(string, abbreviation) {
23 // If the string is equal to the abbreviation, perfect match.
24 if (string == abbreviation) {return 1;}
25
26 var total_character_score = 0,
27 abbreviation_length = abbreviation.length,
28 string_length = string.length,
29 start_of_string_bonus,
30 abbreviation_score,
31 final_score;
32
33 // Walk through abbreviation and add up scores.
34 for (var i = 0,
35 character_score/* = 0*/,
36 index_in_string/* = 0*/,
37 c/* = ''*/,
38 index_c_lowercase/* = 0*/,
39 index_c_uppercase/* = 0*/,
40 min_index/* = 0*/;
41 i < abbreviation_length;
42 ++i) {
43
44 // Find the first case-insensitive match of a character.
45 c = abbreviation.charAt(i);
46
47 index_c_lowercase = string.indexOf(c.toLowerCase());
48 index_c_uppercase = string.indexOf(c.toUpperCase());
49 min_index = Math.min(index_c_lowercase, index_c_uppercase);
50 index_in_string = (min_index > -1) ? min_index : Math.max(index_c_lowercase, index_c_uppercase);
51
52 if (index_in_string === -1) {
53 return 0;
54 } else {
55 character_score = 0.1;
56 }
57
58 // Set base score for matching 'c'.
59
60 // Same case bonus.
61 if (string[index_in_string] === c) {
62 character_score += 0.1;
63 }
64
65 // Consecutive letter & start-of-string Bonus
66 if (index_in_string === 0) {
67 // Increase the score when matching first character of the remainder of the string
68 character_score += 0.6;
69 if (i === 0) {
70 // If match is the first character of the string
71 // & the first character of abbreviation, add a
72 // start-of-string match bonus.
73 // start_of_string_bonus = 1 //true;
74 }
75 }
76 else {
77 // Acronym Bonus
78 // Weighing Logic: Typing the first character of an acronym is as if you
79 // preceded it with two perfect character matches.
80 if (string.charAt(index_in_string - 1) === ' ') {
81 character_score += 0.8; // * Math.min(index_in_string, 5); // Cap bonus at 0.4 * 5
82 }
83 }
84
85 // Left trim the already matched part of the string
86 // (forces sequential matching).
87 string = string.substring(index_in_string + 1, string_length);
88
89 total_character_score += character_score;
90 } // end of for loop
91
92 // Uncomment to weigh smaller words higher.
93 // return total_character_score / string_length;
94
95 abbreviation_score = total_character_score / abbreviation_length;
96 //percentage_of_matched_string = abbreviation_length / string_length;
97 //word_score = abbreviation_score * percentage_of_matched_string;
98
99 // Reduce penalty for longer strings.
100 //final_score = (word_score + abbreviation_score) / 2;
101 final_score = ((abbreviation_score * (abbreviation_length / string_length)) + abbreviation_score) / 2;
102
103 if (start_of_string_bonus && (final_score + 0.15 < 1)) {
104 final_score += 0.15;
105 }
106
107 return final_score;
108};