如何按照自定义模式对字符串数组进行排序

5

我有几个像这样的数组:

var arr1 = ['A', 'B', 'C', 'D'], 
    arr2 = ['A', 'C', 'D'],
    arr3 = ['B', 'D'];

我现在想按照自定义的顺序进行排序,例如 ['D', 'C', 'A', 'B']。我正在使用 lodash 并寻找一种聪明的方法来实现这个。


你希望每个数组都按照相同的模式排序吗? - Jared Smith
3个回答

13

您可以使用对象将值有效地映射到可排序的值:

var arr1 = [ "A", "B", "C", "D" ];

var map = { D: 1, C: 2, A: 3, B: 4 };
arr1.sort(function(x, y){ return map[x] - map[y]; });

// show result in snippet
document.write(JSON.stringify(arr1));


2
与Guffa的解决方案基本相同,但使用可重用的API:
var makeSorter = function(pattern) {
    var map = _.mapValues(_.invert(pattern), Number);
    return function(vals) {
        return vals.sort(function(a, b) {
            return map[a] - map[b];
        });
    };
};


var mySorter = makeSorter(['D', 'C', 'A', 'B']);
mySorter(['A', 'B', 'C', 'D']); //=> ["D", "C", "A", "B"]
mySorter(['A', 'C', 'D']); //=> ["D", "C", "A"]

如果您的数据中可能存在不符合模式的值,则您可能需要更复杂的东西:
var makeSorter = function(pattern) {
    var map = _.mapValues(_.invert(pattern), function(s) {return Number(s) + 1;});
    return function(vals) {
        return vals.sort(function(a, b) {
            return (map[a] || Infinity) - (map[b] || Infinity);
        });
    };
};

mySorter(['A', 'X', 'B', 'C', 'Q']); //=> ["C", "A", "B", "X", "Q"]

还有,ES6的箭头函数真是太棒了。这是ES6中第一个版本的等效代码:

var makeSorter = pattern => {
    let map = _.mapValues(_.invert(pattern), Number);
    return vals => vals.sort((a, b) => map[a] - map[b]);
};

0
var pattern = ['D', 'C', 'A', 'B'];

function sortArray (array, pattern) {
    return array.sort(function (a, b) {
        if (pattern.indexOf(a) === pattern.indexOf(b)) {
            return 0;
        } else {
            return pattern.indexOf(a) > pattern.indexOf(b) ? 1 : -1;
        }
    });
}

// use like:
var sortedArray = sortArray(['A', 'C', 'D'], pattern);

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