JavaScript按字母顺序排序,首先匹配字符串开头,然后按包含文本的字母顺序排序。

10
我需要帮助整理一些数据。 假设我在搜索字段中输入“piz”。返回一个包含所有包含“piz”的条目的数组。
现在我想按照以下顺序显示它们:
pizza 
pizzeria
apizzetto
berpizzo

首先按照我输入的内容以字母顺序排列,然后按照包含我输入的内容的项以字母顺序排列。

如果我按字母顺序排序,我会得到以下结果。

apizzetto
berpizzo
pizza 
pizzeria

有人知道如何做到这一点吗? 感谢您的帮助。

5个回答

15

你可以将数据分成两个数组,一个以输入值开头,另一个则不是。分别对它们进行排序,然后将两个结果合并:

var data = [
    'pizzeria',
    'berpizzo',
    'apizzetto',
    'pizza'
];

function sortInputFirst(input, data) {
    var first = [];
    var others = [];
    for (var i = 0; i < data.length; i++) {
        if (data[i].indexOf(input) == 0) {
            first.push(data[i]);
        } else {
            others.push(data[i]);
        }
    }
    first.sort();
    others.sort();
    return(first.concat(others));
}

var results = sortInputFirst('piz', data);

你可以在这里看到它的运作:http://jsfiddle.net/jfriend00/nH2Ff/


是的,else 应该写成 else if indexOf ... > 0 来排除不匹配的元素。 - georg
非常好。像魔法一样运作。不过我得做一些修改来确保小写匹配。但那是另一个话题了。非常感谢! - Leonardo Amigoni
@thg435 - 如果你仔细阅读问题,初始数组已经被筛选为只包含搜索词的单词。 - jfriend00
@jfriend00:说实话,我甚至没有读问题,只是匆匆看了一下代码,发现了一个缺陷。 - georg

7
正确的完整解决方案是:
var data = [
    'pizzeria',
    'berpizzo',
    'apizzetto',
    'pizza'
];

var _sortByTerm = function (data, term) {
    return data.sort(function (a, b) {
       return a.indexOf(term) < b.indexOf(term) ? -1 : 1;
    });
};

var result = _sortByTerm(data, 'piz');

如果需要对对象进行排序,请使用以下函数:
var _sortByTerm = function (data, key, term) {
     return data.sort(function (a, b) {
        return a[key].indexOf(term) < b[key].indexOf(term) ? -1 : 1;
     });
 };

1
@nickb 这不是 OP 所要求的正确答案 - 虽然它确实解决了按术语第一个索引排序的问题,但 OP 实际上是在询问两个单独的排序,这才是被接受的答案。 - Randy Hall
@RandyHall 我犯了一个错误——我正在寻找整个字符串匹配的第一个索引(这对我来说似乎很合理),而不是第一个字符匹配,然后按字母顺序排列非第一个字符匹配的字符串。我没有仔细阅读问题标题。已删除我的注释。 - nickb

3

使用reduce函数:

const data = ['pizzeria', 'berpizzo', 'pizza', 'apizzetto'];

function sortInputFirst(input, data) {
    data.sort();
    const [first, others] = data.reduce(([a, b], c) => (c.indexOf(input) == 0 ? [[...a, c], b] : [a, [...b, c]]), [[], []]);
    return(first.concat(others));
}

const output = sortInputFirst('piz', data);
console.log(output)

非常优雅。您能否提供更多解释? - Kaya Toast

2
这是另一个例子:
var str = 'piz';
var arr = ['apizzetto','pizzeria','berpizzo','pizza'];

arr.sort(function(a,b) {
    var bgnA = a.substr(0,str.length).toLowerCase();
    var bgnB = b.substr(0,str.length).toLowerCase();

    if (bgnA == str.toLowerCase()) {
        if (bgnB != str.toLowerCase()) return -1;
    } else if (bgnB == str.toLowerCase()) return 1;
    return a < b ? -1 : (a > b ? 1 : 0);
});

console.log(arr);

0

以下是我如何使用得票最高的答案来使我的搜索功能使用规范化的数据集。它在比较字符串之前会去除重音符号,并且不区分大小写。

function getAutocompleteNormalizedMatches(userInput, array) {
    const normalizedInput = getNormalizedString(userInput);
    let normalizedListItem;
    let startsWith = [];
    let anywhere = [];
    for (let i = 0; i < array.length; i++) {
        normalizedListItem = getNormalizedString(array[i]);
        if (normalizedListItem.indexOf(normalizedInput) === 0) {
            startsWith.push(array[i])
        } else if (normalizedListItem.includes(normalizedInput)) {
            anywhere.push(array[i])
        }
    }
    startsWith.sort();
    anywhere.sort();
    return startsWith.concat(anywhere);
}


const getNormalizedString = function (str) {
    str = str.replace(/\s+/g, " ").trim();
    return (str ? removeDiacritics(str.toLowerCase()) : "");
};

如果您不需要removeDiacritics()函数,可以参考此链接,因为它会占用很多无用的空间:使用JavaScript删除字符串中的重音和变音符号


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接