【问题标题】:Jquery logic to sort select options by number of word matchesJquery逻辑按单词匹配数对选择选项进行排序
【发布时间】:2011-07-28 11:09:10
【问题描述】:

我想要一些类似于 Mysql 的数据排序的东西,但是在 jquery 中。我有一个输入和一个选择标签,就像这样 -

我希望根据输入文本的值对选择选项进行过滤和排序。

  • 过滤 OR 逻辑应用于输入文本和所有要保留的至少包含一个单词的选项
  • 排序/分组然后按匹配数对剩余选项进行排序,使得包含输入中所有单词的选项显示在顶部,然后是那些少一个单词的选项,依此类推。以下仅为示例,可能不准确 -

我已经完成了过滤部分的逻辑。现在是排序部分,我不知道该怎么做。

举个例子,说输入文本贴出一串 5 个单词。我不知道 jQuery 中是否有类似于 Mysql 的 order by 可以返回排序选项。所以,我的逻辑是这样的(伪代码)-

var numberOfWords;
sortedOptions = new Array();
for(cnt=numberOfWords; cnt>0; cnt --)
{
    find options containing exactly those many words
    append them to array sortedOptions
}

现在考虑 numberOfWords = 5 和 cnt=3 的情况。 3 个单词有很多可能的组合,我需要检查这些组合以准备具有 3 个单词匹配的选项。这很好,但是当字数增加时,代码的时间复杂度又如何呢?有没有更好的优化方式?

请注意 - 这种检查可能需要在用户输入时进行(在每个按键上),并且我不能如此频繁地访问后端数据库。我还没有找到任何用于相同目的的现成插件。请检查我之前关于此的问题Any jquery 1.3 compatible plugin to filter dropdown using user text input plus grouping based on number of input strings matched。如果您知道任何可以解决问题的插件,请在此处发布。但无论如何都期待这个问题的解决方案。

谢谢

【问题讨论】:

    标签: javascript jquery sorting options


    【解决方案1】:

    类似的东西(并不完全有效):

    $(function(){
      var $select = $('#mySelectBox'), nonMatches = [], $text = $('#myTextBox').keyup(function(){
          // find all the words
          var words = $text.val().split(' '), options = []
        // nonMatches is an array of <option>s from the prev search that didn't match
        // we put them back in the <select>
        for (var i in nonMatches)
          $select.append(nonMatches[i])
        nonMatches = []
        // and clear all the old labels like "1 word match"
        $select.find('optgroup').each(function(){
          var $this = $(this)
          $this.replaceWith($this.html())
        })
        // if the textbox is blank, dont need to search
        if (!words.length)
          return
        // loop thru each <option>
        $select.find('option').each(function(){
          var wordCount = 0, $this = $(this), html = ' ' + $this.html().toLowerCase() + ' '
          // loop thru each word and check if the <select> contains that word
          for (var i in words) {
            if (html.indexOf(' ' + words[i].toLowerCase() + ' ') > -1)
              wordCount++
          }
          // if this <option> doesn't have any of the words, save and remove it
          if (wordCount == 0)
            nonMatches.push($this.remove())
          else {
            // otherwise, save it to be sorted
            if (!options[wordCount])
              options[wordCount] = []
            options[wordCount].push($this.remove())
          }
        })
        // the options array holds all the <option>s that match; we need to sort it
        keys = [], sortedOptions = []
        for (var i in options) {
          keys.push(i)
        }
        keys.sort()
        keys.reverse()
        for (var i in keys)
          sortedOptions[keys[i]] = options[keys[i]]
        for (var i in sortedOptions) {
          // put the matches in the <select>
          $select.append('<optgroup label="' + (i == words.length ? 'All' : i) + ' word match">')
          for (var j in sortedOptions[i]) {
            $select.append(sortedOptions[i][j])
          }
          $select.append('</optgroup')
        }
      })
    })
    

    【讨论】:

    • 当然亚伯拉罕... :) 谢谢你的尝试,你也可以告诉我你的想法的伪代码......
    • 好吧,您不会为每个单词组合检查每个
    • 你是对的,循环遍历选项而不是每个单词组合会更快。需要检查很长的代码...您能为此写一个解释或伪代码吗?
    • wooooo 这行得通,虽然我做了一些修改。稍后将分享代码。为您 +1。 每个人都支持这个人...很棒的努力...虽然会分析最佳答案...
    【解决方案2】:

    您可以使用数组过滤器过滤掉结果。这将为您提供一个子元素数组。

    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/filter

    function isBigEnough(element, index, array) {
      return (element >= 10);
    }
    var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
    // filtered is [12, 130, 44]
    

    您可以使用排序功能按长度排序

    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort

    var numbers = ["aa", "b"];
    
    numbers.sort(function(a, b) {
       return a.length - b.length;
    });
    

    【讨论】:

    • 嗯我想我需要检查一下 .sort() 的事情。那么,看起来排序函数会为每组连续的数组键调用?在这种情况下,如果我检查这两个连续值与输入单词的匹配数并基于此返回差异,最后我有一个排序数组?是吗?
    • 您可以对整个单词列表进行排序。当您回显它时,您可以根据需要添加到 opt 组中
    猜你喜欢
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多