数组排序不正确/不可预测,使用 indexOf 时



我正在尝试使用数组排序方法和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;
                }
              });

相关内容

最新更新