Jquery logic to sort select options by number of word matches

主宰稳场 提交于 2019-12-24 08:43:52

问题


I want something similar to Mysql's sorting of data, but in jquery. I have an input and a select tag, like this -

I want the select options to be filtered and sorted depending on the input text's value.

  • Filtration OR logic to be applied on the input text and all those options to be kept which contain at least one word
  • Sorting/Grouping then sort the remaining options by number of matches, such that options containing all the words as in the input appear at the top, followed by those with one less words and so on. Following is just an illustration and may not be exact -

I am done with the logic of the filtration part. Now comes the sorting part and I am not sure how to do.

Taking an example, say input text posted a string of 5 words. I don't know if there something in jQuery similar to Mysql's order by which can return me the sorted options. So, my logic is like this (pseudocode)-

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

Now consider the case where numberOfWords = 5 and cnt=3. There are many possible combinations of 3 words, which I need to check to prepare the options with 3 word matches. That's fine but what about the time complexity of the code, when the number of words increases? Is there a better optimized way?

Please note - This checking may need to be done while the user is typing (on every key up) and I can't hit the backend database so frequently. I have not yet found any readymade plugin for the same purpose. Please check my earlier question Any jquery 1.3 compatible plugin to filter dropdown using user text input plus grouping based on number of input strings matched regarding this. If you know any plugin which can solve the problem please post there. But looking forward for a solution to this anyway.

Thanks


回答1:


Something along the lines of this (doesn't completely work):

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



回答2:


You could filter out the result using array filter. This will give you an array of sub elements.

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]

You could sort by length using the sort function

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


来源:https://stackoverflow.com/questions/6857969/jquery-logic-to-sort-select-options-by-number-of-word-matches

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!