【问题标题】:Match string with array of string in any order以任意顺序将字符串与字符串数组匹配
【发布时间】:2016-01-23 15:31:30
【问题描述】:

我的输入是一个字符串,它可能是人的名字、姓氏、组合,甚至是两者的一部分,按特定顺序排列

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

如果用户的输入是“John”,我们的 John 的 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˙函数匹配。也就是说,为什么˙"John rk"˙ 是假的,无论您多么努力,都可以按特定顺序将具有˙"john rk"˙ 的字符串组合在一起。你可以有˙"John Mark"˙,但是这不会匹配使用˙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



我认为,使用所有名称(名字、姓氏和分隔的中间名)创建数组并匹配所有可能的组合可能是可行的方法,但由于必须在此之前完成,我想知道是否有更好的方式。

如果没有更好的方法,如何以尽可能少的处理能力从数组中做出所有可能的组合?

【问题讨论】:

  • 为什么"John rk" 会返回false
  • 就好像你会在"Jonh Mark"上做indexOf一样
  • 逻辑不清楚,在这里。不确定"hn mar" 如何返回true,而"John rk" 可以返回false?请参阅 "如果用户的输入是 'John',我们的 John 的 hasPresent 方法应该返回 true" 处的 OP。 "rk" 如何在输入字符串的开头否定 "John" ? , 其中字符串的两个部分都以全名找到
  • 由于我们严格需要将整个输入与人名的任何顺序相匹配,因此John ma 很重要。如果他的名字的顺序正确的话,可以不间断地在一件中找到它
  • @JuanBoca 的更新答案应该满足要求,保留"John rk" 的情况

标签: javascript arrays match string-matching


【解决方案1】:

你可以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;
}

这将为您的示例以及“Joh Smi”之类的示例返回 true,但区分大小写。如果需要,您可以对其进行调整以使其不区分大小写。

【讨论】:

  • 这并没有解决“n n n”作为输入字符串的问题
  • 好的,我以前没见过这个限制。我可以适应它。对于 h hi iJo s 这样的情况,这是否应该返回 true?
  • 不,谢谢,它必须是连续字符串,匹配为 John Mark 的 "hn ma"...
  • 您可以删除每个匹配字符串之前的所有内容,然后检查下一个字符或单词。因此,对于“hn mar”这样的情况,它将返回 true,但对于“mar hn”,它将返回 false。这对你有用吗?
  • 检查编辑的函数。这适用于您的示例,除了John rk,我同意@guest271314,这对我来说看起来不一致
【解决方案2】:

如果你有一个完整的字符串,你可以检查int indexOf(String str),如果它不是-1,你就知道字符串包含单词。如果你想将一个数组变成这个长字符串,只需执行类似

for (int i = 0; i < strArray.length; i++)
{
    someStr += strArray[i];
}

然后检查 someStr.indexOf("John");

【讨论】:

  • This is javascript no int ;) 但明白了你的意思...问题是,我不知道按巫术顺序是用户用来过滤人的
  • 啊抱歉,我回答时你的标签是“Java”,我的错。
【解决方案3】:

编辑、更新

把它当作你会做indexOf on

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")
           )

【讨论】:

  • 在这种情况下,用户必须写一个全名,但有趣的想法
  • @Akxe “在这种情况下,用户必须写一个全名” 不确定解释正确吗?如果需要输入的是用户全名,re 应该返回true
  • 输入可以是例如“hn ma”至于约翰马克......对不起
  • @Akxe "输入可以是例如 John mark 的 "hn ma"。" "hn ma" 应该返回 false,对吗?是否要求返回 true 以在输入中找到与在Class 中找到的用户名的任何部分匹配的任意两个字符?
  • @Akxe 如果要求检查所有可能的组合,首先需要创建一个或多个所有可能组合的数组以进行检查。当考虑到评论 " 它必须是连续的字符串,即匹配 " 。也许花点时间细化实际问题,提出包括所有必需元素的新问题?目前,在这里,实际问题似乎不清楚;现在至少与最初发布的 Question 不同。不确定"John Sm" 应该如何返回true"John rk" 应该如何返回false
【解决方案4】:

这是一种美。我的任何订单都尽可能少的循环。

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

【讨论】:

  • @JuanBoca 这是我想要的……如果你有更好的名字来解决这个问题,请重命名它,这样也很有帮助:)
  • @guest271314 就是这样,希望你现在明白了
猜你喜欢
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
相关资源
最近更新 更多