Сопоставить строку с массивом строки в любом порядке
Мой ввод - это строка, это может быть имя, фамилия, комбинация или даже часть обоих, в определенном порядке.
Class {
first = 'John' // just simple string
last = 'Smith' // just simple string
middle = 'Mark Bill' // this is often empty string, but may contain multiple, divided by spaces. ('' or 'Mark Bill')
hasPresent(what){
return true || false
}
}
Если пользователь вводит "Джон", наш Джон hasPresent
метод должен вернуть true
Другие случаи:
"input" => expected result
"Smith" => true
"mark" => true
"John Mark" => true
"hn mar" => true
"m" => true
" " => true
"John John" => false
"John Mark John" => false
"Jo Mark" => false
"John rk" => false
"n n n" => false
Для лучшего понимания представьте, что вы можете заказывать имена людей в любом порядке, если вы используете их только один раз. Затем возьмите ввод и сопоставьте его с помощью функции "indexOf". То есть, почему k"John rk" false ложно, что бы вы ни старались, вы можете собрать строку, имеющую k"john rk" ˙ в этом конкретном порядке. У вас может быть John "John Mark" match, но это не будет совпадать с использованием ˙indexOf˙.
Из наших имен мы можем сопоставить все, что соответствует любой из следующих строк
"John Smith Mark Bill","John Mark Smith Bill","John Bill Smith Mark","John Mark Smith Bill","John Smith Bill Mark", "John Mark Bill Smith" etc
Я думаю, что создание массива со всеми именами (имя, фамилия и разделенные отчества) и сопоставление со всеми возможными комбинациями может быть способом, но так как это должно быть сделано раньше, я хотел бы знать, есть ли лучший путь.
Если нет лучшего способа, как сделать все возможные комбинации из массива с минимально возможной вычислительной мощностью?
4 ответа
Вы можете concat
все имена и для каждого слова, которое вводит пользователь, проверьте, присутствует ли оно в строке.
first = 'John';
last = 'Smith';
middle = 'Mark Bill';
searchStr = first + " " + middle + " " + last;
function hasPresent(param){
searchLower = searchStr.toLowerCase();
searchWords = param.toLowerCase().split(" ");
for (i = 0; i < searchWords.length; i++){
index = searchLower.indexOf(searchWords[i])
if (index == -1){
return false;
}
searchLower = searchLower.substring(0,index) + searchLower.substring(index + searchWords[i].length, searchLower.length);
}
return true;
}
Это вернет true для ваших примеров, а также для примеров типа "Joh Smi", но с учетом регистра. Вы можете адаптировать его, чтобы сделать его нечувствительным к регистру, если вам нужно.
Если бы у вас была целая строка, вы могли бы просто проверить int indexOf(String str)
и если это что-то кроме -1, вы знаете, что строка содержит слова. Если вы хотите превратить массив в эту длинную строку, просто сделайте что-то вроде
for (int i = 0; i < strArray.length; i++)
{
someStr += strArray[i];
}
затем проверить someStr.indexOf("John");
Изменить, Обновлено
Примите это так, как если бы вы сделали
indexOf
на
var fullname = "John Mark Bill Smith";
var checkname = fullname.toLowerCase().indexOf(input.toLowerCase()) !== -1;
var fullname = "John Mark Bill Smith";
var check = function(input) {
return fullname.toLowerCase().indexOf(input.toLowerCase()) !== -1
}
console.log(check("Smith")
, check("mark")
, check("John Mark")
, check("hn mar")
, check("m")
, check(" ")
, check("John John")
, check("John Mark John")
, check("Jo Mark")
, check("John rk")
, check("n n n")
)
Это красота, которая делает это. Любой заказ с минимальным количеством циклов.
hasPresent(what:string|number):boolean {
if(isNumber(what)){
return this.tel.hasPresent(what)
}else{
if (this.tel.hasPresent(what)) {
return true
}else{
var query = what.toString().toLowerCase().split(' ')
var possible = this.name.toLowerCase().trim().split(' ')
if(query.length > possible.length){
return false // No way this could be met
}
for (var i = possible.length - 1; i > 0; i--) {
var possible2 = this.name.toLowerCase().trim().split(' ')
if(possible[i].hasPresent(query[0])){
if (query.length==1){
return true
}
possible2.remove(possible[i])
for (var j = 1; j < query.length; j++){
var passed = false
for (var k = possible2.length - 1; k > 0; k--) {
if(possible2[k].indexOf(query[j]) == 0){
possible2.remove(possible2[k])
passed = true
break
}
}
if(!passed){
break
}
}
if(passed){
return true
}
}
}
return false
}
}
}
Примечание:
Array.remove(object) - removes object for array
Array|String.hasPresent(needle) - shortcut for indexOf(needle) => 0