Предполагая:
- порядок соответствия
str
имеет значение, - вы хотите элемент в списке, который соответствует самой длинной части поискового слова,
- и элемент, наиболее соответствующий началу
str
;
эта функция должна сделать это:
var list = ['Mr. Adam Smith Junior', 'Anna Smith Jr.', 'Adam Jhon Smith', 'Smith Adam'];
var str = 'Adam Smith Jr.';
function onlyUnique(value, index, self) {
// See: https://stackoverflow.com/a/14438954/2142071
return self.indexOf(value) === index;
}
function getBestMatch(word, list, minimal_length) {
// Minimal length is used to make the search more meaningful;
// single character searches would not be helpful most of the times
if ( word.length < minimal_length ) {
return ['', -1]; // None found, word is too short
}
// Pre-process search RegEx patterns
var patterns = [];
var words = [];
// For all possible starting positions inside `word`:
// So:
// Adam Smith Jr.
// dam Smith Jr.
// am Smith Jr.
// .. etc ..
for (var i = 0; i <= word.length - minimal_length; i++) {
var temp_word = word.substring(i);
// For every part of the remainder of `word`:
// So:
// Adam Smith Jr.
// Adam Smith Jr
// Adam Smith J
// .. etc ..
for (var j = minimal_length; j <= temp_word.length; j++) {
// Add that word part to a central array of patterns to search for in list
var word_part = temp_word.substring(0, j);
words[ words.length ] = word_part;
}
}
// Sort all unique word parts
words = words.filter( onlyUnique );
words.sort(function(a, b){
// (longest parts first, since they are assumed a better match)
return b.length - a.length;
});
// For every word part:
for (var i = 0; i < words.length; i++) {
// Create RegEx pattern
var pattern = new RegExp( words[ i ] );
// Search each item in the list using this pattern for a match.
for (var n = 0; n < list.length; n++) {
if ( words[ i ].length <= list[ n ].length ) {
if ( pattern.test( list[ n ] ) ) {
// Return the first match and its index
return [list[ n ], n];
}
}
}
}
return ['', -1]; // None found
}
var match = getBestMatch(str, list, 2);
// match[0] is the matched item
// match[1] is the index of that item in the list
console.log( match[0], 'at index', match[1] );
Примечание: Имейте в виду сложность, которую уже имеет эта функция без учета таких проблем, как:
- Должно ли слово в
str
соответствовать в целом? - Могут ли совпадения частей в
str
быть в другом порядке? - А как насчет слов с ошибками?
- .. et c ..
- А какой счет / значение следует отнести к совпадению (например, Что определяет «лучшее» совпадение?)
- Должно ли оно вернуть все совпадения с лучший результат или только один? (А какой?)
- Производительность: сколько возможных частей слова нужно сгенерировать и поиск (для каждого элемента в
list
)
Следовательно , поиск - это собственное программирование. ;)