如何在javascript中按单词顺序匹配两个字符串?
需要找到与给定字符串最匹配的字符串如何在javascript中按单词顺序匹配两个字符串?,javascript,string-matching,Javascript,String Matching,需要找到与给定字符串最匹配的字符串 list = ['Mr. Adam Smith Junior', 'Anna Smith Jr.', 'Adam Jhon Smith', 'Smith Adam']; str = 'Adam Smith Jr.'; // output: 'Mr. Adam Smith Junior' 我已经尝试过标记单词,对于列表中的每一项,它都与2个单词匹配(Adam/Smith/Jr.)。但我的预期输出是列表[0]。因此,我需要一个解决方案,通过最匹配的单词序列找到
list = ['Mr. Adam Smith Junior', 'Anna Smith Jr.', 'Adam Jhon Smith', 'Smith Adam'];
str = 'Adam Smith Jr.';
// output: 'Mr. Adam Smith Junior'
我已经尝试过标记单词,对于列表中的每一项,它都与2个单词匹配(Adam/Smith/Jr.)。但我的预期输出是列表[0]。因此,我需要一个解决方案,通过最匹配的单词序列找到匹配的字符串。编辑:
看起来你在寻找最连续的单词数。这是一个完全可以做到这一点的版本:
var list = ['Mr. Adam Smith Junior', 'Anna Smith Jr.', 'Adam Jhon Smith', 'Smith Adam'];
var str = 'Adam Smith Jr.';
/**
* Representing a class to search and match a string in a list of strings
* @param {string[]} data An array consists of input strings to search in
* @param {string} query A string to search for
*/
var TextMatcher = function(data, query) {
this.wordsToSearch = extractWords(query);
/** @type {any[]} */
this.results = [];
var $this = this;
data.forEach(function(ele, idx) {
var words = extractWords(ele);
var start = findSearchStartPoint(words, $this.wordsToSearch);
var numberOfMatches = findNumberOfMatches(words, $this.wordsToSearch, start);
$this.results.push({
words: words,
wordsToSearch: $this.wordsToSearch,
firstListMatchedIndex: start.firstListMatchedIndex,
numberOfMatches: numberOfMatches,
index: idx
});
});
// The logic can be improved by using regular expression
/**
* Simply breaks down a string to its words
* @param {string} s The input string
*/
function extractWords(s) {
return (s || '').split(' ');
}
/**
* @typedef {Object} SearchPoint Starting point of search
* @property {number} startIndex - Index of `wordsToSearch` element
* @property {number} firstListMatchedIndex - Index of `words` element
*/
/**
* Finds the starting point of the search. In other words, it returns the first word in `wordsToSearch`
* that matches the first word in `words`
* @param {string[]} words The array in which search will be done
* @param {string[]} wordsToSearch The array of words that needs to be searched for
* @returns {SearchPoint} Returns indices of each input array from which search should start
*/
function findSearchStartPoint(words, wordsToSearch) {
var startIndex = wordsToSearch.length;
var firstListMatchedIndex = -1;
for (var i = 0; i < wordsToSearch.length; i++) {
firstListMatchedIndex = words.findIndex(function(w, x) {
return x > firstListMatchedIndex
&& wordsToSearch[i].toLowerCase() === w.toLowerCase();
});
if (firstListMatchedIndex > -1) {
startIndex = i;
break;
}
}
return {
startIndex: startIndex,
firstListMatchedIndex: firstListMatchedIndex
};
}
/**
* Returns number of consecutive `wordsToSearch` elements in `words` starting
* from `start`
* @param {string[]} words The array in which search will be done
* @param {string[]} wordsToSearch The array of words that needs to be searched for
* @param {SearchPoint} start
*/
function findNumberOfMatches(words, wordsToSearch, start) {
var numberOfMatched = 0;
if (start.firstListMatchedIndex > -1) {
numberOfMatched = 1;
for (var i = start.startIndex + 1; i < wordsToSearch.length; i++) {
if (wordsToSearch[i].toLowerCase() === (words[i + start.firstListMatchedIndex] || '').toLowerCase()) {
numberOfMatched++;
} else {
break;
}
}
}
return numberOfMatched;
}
};
/**
* Sends a summary of how the search performed to `console`
*/
TextMatcher.prototype.showResutls = function() {
console.info('Words to be searched:')
console.info(this.wordsToSearch);
console.info('\n');
this.results.forEach(function(r) {
console.info(r.words);
console.info('List item ' + r.index + ' ---- No. of words matched: ' + r.numberOfMatches
+ (r.numberOfMatches > 0 ? ', First word matched: ' + r.words[r.firstListMatchedIndex] : ''));
});
console.info('\n');
};
/**
* Displays which `data` item has the most number of matched consecutive words in `console`
*/
TextMatcher.prototype.mostMatched = function() {
var max = Math.max(...this.results.map(function(el) {
return el.numberOfMatches;
}));
return this.results.find(function(el) {
return el.numberOfMatches === max;
});
};
// Creates an instance of TextMatcher
var search = new TextMatcher(list, str);
// Shows results in console
search.showResutls();
// Gets the most matched item in the list
var res = search.mostMatched();
// Shows the most matched item in console
console.info('The phrase with the most consecutive words matched:');
console.info('Phrase: "' + list[res.index] + '", No. of words matched: ' + res.numberOfMatches + ', Index: ' + res.index);
如果这还不是你想要的,请告诉我
==================================
初始职位:
我想知道你是否在找这样的东西:
//Words to be searched:
//[ 'Adam', 'Smith', 'Jr.' ]
//[ 'Mr.', 'Adam', 'Smith', 'Junior' ]
//List item 0 ---- No. of words matched: 2, First word matched: Adam
//[ 'Anna', 'Smith', 'Jr.' ]
//List item 1 ---- No. of words matched: 1, First word matched: Smith
//[ 'Adam', 'Jhon', 'Smith' ]
//List item 2 ---- No. of words matched: 1, First word matched: Adam
//[ 'Smith', 'Adam' ]
//List item 3 ---- No. of words matched: 1, First word matched: Adam
//The phrase with the most consecutive words matched:
//Phrase: "Mr. Adam Smith Junior", No. of words matched: 2, Index: 0
var list = ['Mr. Adam Smith Junior', 'Anna Smith Jr.', 'Adam Jhon Smith', 'Smith Adam'];
var str = 'Adam Smith Jr.';
// This loop finds the best matching string in the array and
// and prints it in the console
function findBestMatch(arr, s) {
for (var i = s.length; i > 1; i--) {
var found = arr.find(function(ele) {
return ele.indexOf(s.substr(0, i)) > -1;
}) || [];
if (found.length) {
console.info(found);
break;
}
}
}
findBestMatch(list, str);
//您的代码请求-更新的代码。
var列表=[“小亚当·斯密先生”、“小安娜·斯密”、“亚当·斯密”、“斯密·亚当”];
var str='小亚当·斯密';
//更新代码。
str=str.split(“”);
var i=0,j=0;
var匹配=[];
//“list”变量数组遍历每个字符串的第一个循环。
而(i
您能否提供一个您现在拥有的“有效”示例?您是否希望最长的匹配零件作为决定性因素?这应该是相同的顺序吗?(所以“斯密-亚当”应该只匹配两个单词中的一个)有很多可能的解决方案,但是为了给出更好的答案,你能详细说明它应该匹配什么和不应该匹配吗?(所有的str
必须匹配还是只匹配开头或结尾(一部分)?“亚当”和“亚当·斯密”一样好吗?…等等)你能告诉我你想要的输出吗。所以我可以根据你的要求更新代码。
// Your code request - Updated code.
var list = ['Mr. Adam Smith Junior', 'Anna Smith Jr.', 'Adam Jhon Smith', 'Smith Adam'];
var str = 'Adam Smith Jr.';
// Updated code.
str = str.split(' ');
var i = 0, j = 0;
var matched = [];
// First loop for your `list` variable array to go through each string.
while(i < str.length){
// Second loop for your `str` variable to match each part of string with your `list` variable's each string.
for(j=0;j < list.length;j++){
var match = new RegExp( str[i], 'g' );
if(list[j].match(match)){
// Find exact match - Your code goes here.
if(!matched.includes(list[j])){
matched.push(list[j]);
}
}
}
i++;
}
// Your result of find the all matched values from `list` variable.
console.log(matched);