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

时间:2016-01-22 13:45:20

标签: javascript jquery arrays ajax sorting

我尝试使用Array排序方法和indexOf对自动填充建议进行排序。用户的当前搜索词将插入indexOf。

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

似乎是半工作。例如,如果你键入" Eternal"你得到一个看似正确排序的列表。但是,如果你然后删除' l'从那个词来看,这个名单立即变得混乱。

然而,它并不仅仅在第二次搜索时搞砸......例如,如果你开始干净并只是搜索A',建议"机械师:复活&#34 ;显示为第二个建议。

奇怪的是,如果你搜索" 200",你会得到结果" 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);
            });
        }
    });
}

2 个答案:

答案 0 :(得分: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;
                }
              });

答案 1 :(得分: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
            }
        });
    })
}   

也许您仍然需要根据您的偏好调整排序,但它应该返回更稳定的结果