2016-01-22 84 views
0

我想排序使用數組排序方法和indexOf自動完成建議。用戶的當前搜索詞將被插入到indexOf中。使用indexOf時,數組排序不正確/不可預測?

這裏是小提琴: https://jsfiddle.net/neowot/km1uvzo0/

這似乎一半的工作。例如,如果你輸入「Eternal」,你會得到一個看似正確的排序列表。但是,如果你從這個術語中刪除'l',那麼這個列表立即變得混亂。

但是,它不僅會在第2次搜索時搞砸......例如,如果您開始清理並搜索'A',則建議「Mechanic:Resurrection」顯示爲第二個建議。

奇怪的是,如果你搜索「200」,你會在第3次得到結果「Payuk Mhek」 - 再次。

我找不出爲什麼會出現這些錯誤。請讓我知道你是否可以幫忙。謝謝。

function AutoComplete() { 
    $(".searchbox").autocomplete({ 
     source: function(request, response) { 
      $.when(GetMovies(request), 
        GetTV(request)) 
      .done(function() { 
       combine = results1.concat(results2).slice(0, 15); 

       combine.sort(function(a, b){  
        if (b.value.indexOf(request.term) - a.value.indexOf(request.term) < 1) { 
         return 1; 
        } 
        else if (b.value.indexOf(request.term) - a.value.indexOf(request.term) > 1) { 
         return -1; 
        } 
        else { 
         return 0; 
        } 
       }); 

       response(combine); 
       console.log(combine); 
      }); 
     } 
    }); 
} 
+0

'results1'和'results2'沒有在你的代碼中定義,'combine'應該是'var'。 – Tomalak

+0

@Tomalak,他們在他的完整代碼小提琴中,因爲這只是完整代碼的一小部分。 – Lucero

+0

不,你正在使用全局變量,因爲你做錯了。比較:https://jsfiddle.net/km1uvzo0/1/最大的變化是支持jQuery Ajax請求返回promise的事實,請參閱'.then()'的使用。但還有其他各種小變化,仔細觀察。 – Tomalak

回答

2

例如,因爲你切的結果,他們進行排序

我之前重寫代碼

$(".searchbox").on("input", AutoComplete); 

function AutoComplete() { 
    $(".searchbox").autocomplete({ 
     source: function(request, response) { 
      $.when(GetMovies(request), GetTV(request)) 
      .done(function(movies, tv) { 

       var term = request.term.toLowerCase(); 
       var combine = movies.concat(tv) 
        .map((v,i) => { 
         //don't have to compute the index for every combination 
         //precompute such values if possible 
         return { 
          titleLowerCase: v.value.toLowerCase(), 
          termOffset: (v.value.toLowerCase().indexOf(term)+1) || Infinity, 
          //and keep a reference to the original data 
          data: v 
         } 
        }) 
        .sort((a, b)=>{ 
         //sortOn(termOffset ASC, titleLowerCase ASC) 
         return (a.termOffset - b.termOffset) || 
         (a.titleLowerCase !== b.titleLowerCase && a.titleLowerCase > b.titleLowerCase? 1: -1) || 0; 
        }) 
        .map(v => v.data).slice(0, 15); 

       response(combine); 
       console.log(combine); 
      }); 
     } 
    }); 
} 

function GetMovies(request) { 
    //Replace spaces with a '+' 
    var url = request.term.replace(/\s/g,"+"); 
    return $.ajax({ 
     'url': 'https://api.themoviedb.org/3/search/movie?api_key=420b889ac6f9e4a1e2dc541624d12fc6&query=' 
     + url, 
     'dataType': 'json' 
    }).then(function(data) { 
     return $.map(data.results || [], function(v,i){ 
      return { 
       label: v.title + ' MOVIE (' + v.release_date + ')', 
       value: v.title 
      } 
     }); 
    }); 
} 

function GetTV(request) { 
    //Replace spaces with a '+' 
    var url = request.term.replace(/\s/g,"+"); 
    return $.ajax({ 
     'url': 'https://api.themoviedb.org/3/search/tv?api_key=420b889ac6f9e4a1e2dc541624d12fc6&query=' 
     + url, 
     'dataType': 'json' 
    }).then(function(data){ 
     return $.map(data.results || [], function(v,i){ 
      return { 
       label: v.name + ' TV (' + v.first_air_date + ')', 
       value: v.name 
      } 
     }); 
    }) 
} 

也許你仍然需要通過自己的喜好來調整排序,但它應該返回的方式更穩定的結果

+0

謝謝你的迴應,但我正在努力讓這個運行... https://jsfiddle.net/neowot/km1uvzo0/2/有什麼明顯的我失蹤了嗎? – matthew

+1

我在編輯時引入了一個錯誤。將其固定在答案中。你可以擺脫這些全局陣列,看看:https://jsfiddle.net/km1uvzo0/4/ – Thomas

+0

哇。謝謝。這非常令人驚喜! – matthew

2

你想要達到什麼樣的目標?

indexOf可能不會做你所期望的;它返回字符串中的位置,如果找不到則返回-1,並區分大小寫。

現在很可能很多結果會有相同的indexOf結果;則應該通過添加其他搜索條件,而不是在你的比較函數返回0,像這樣解釋的話:

   combine.sort(function(a, b) { 
       a = a.value.toUpperCase(); 
       b = b.value.toUpperCase(); 
       var term = request.term.toUpperCase(); 
       if (a.indexOf(term) > b.indexOf(term)) { 
        return 1; 
       } else if (a.indexOf(term) < b.indexOf(term)) { 
        return -1; 
       } else if (a > b) { 
        return 1; 
       } else if (a < b) { 
        return -1; 
       } else { 
        return 0; 
       } 
       }); 
+0

我正在努力使上面的結果是最接近用戶查詢的結果。 – matthew

+1

@matthew,你如何確切地認爲「最密切」? – Lucero

+0

我希望搜索結果的第一個單詞排在頂部,然後再排序第二個單詞結果,依此類推。如果可能的話,每個分組將按字母順序排序。我認爲這是最好的。 – matthew