我正在尝试使用数组排序方法和indexOf对自动完成建议进行排序。用户的当前搜索词将入到 indexOf 中。
这是小提琴:https://jsfiddle.net/neowot/km1uvzo0/
它似乎工作了一半。例如,如果您键入"永恒",您将获得一个看似正确排序的列表。但是,如果您随后从该术语中删除"l",列表会立即变得混乱。
但是,它不仅会在第二次搜索中搞砸......例如,如果您开始清洁并仅搜索"A",则建议"机械师:复活"将显示为第二个建议。
奇怪的是,如果你搜索"200",你会得到结果"Payuk Mhek"排在第3位 - 再次。
我无法弄清楚为什么会发生这些错误。如果您可以提供帮助,请告诉我。谢谢。
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);
});
}
});
}
因为在对结果进行排序之前对结果进行切片
我已经重写了你的代码
$(".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
}
});
})
}
也许您仍然需要根据自己的喜好调整排序,但它应该返回更稳定的结果
你想实现什么样的目标?
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;
}
});