Jquery逻辑用于按字匹配的数量对选择选项进行排序

时间:2011-07-28 11:09:10

标签: javascript jquery sorting options

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

enter image description here

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

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

enter image description here

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

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

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。如果您知道任何可以解决问题的插件,请在那里发布。但无论如何都期待着解决这个问题。

由于

2 个答案:

答案 0 :(得分:3)

有些事情(不完全有效):

$(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')
    }
  })
})

答案 1 :(得分:0)

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

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