按照自定义字母顺序对数组进行排序

5
如何对这样的数组进行排序:
['apple','very','auto','tom','tim','violet'....]

为了按照v、a、t、x、b等顺序排列它(不是按字母顺序),请进行排序。
['violet','very','auto','tom','tim',...]

在脚本中,我会这样做:
myArray.sort('v','a','t'...)

我该如何在JavaScript中实现它?


期望的输出是什么? - dsharew
类似于这样的东西 > 几乎像是一个.orderby['紫罗兰','非常','自动','汤姆','蒂姆',...] - user2185210
K,好的,明白了,我的答案一定对你有用。 - dsharew
谢谢,我也从你的语法中学到了新东西 :) - user2185210
2个回答

6
你可以维护一个字母优先级的数组,并按照该数组中第一个字母的索引进行排序,sort 方法可实现此功能。
这个版本会将任何不以你所指定的字符开始的输入放置在排序后的数组末尾,按照正常(区域敏感)的字母顺序排列。
var order = ['v','a','t'];
var input = ['violet', 'EXTRA 2', 'very','auto','tom','tim', 'EXTRA 1'];
input.sort(function(a, b) {
  // are the strings equal?
  if(a === b) {
    return 0;
  }

  // if they are not equal, compare the first letters
  //  against the custom sort order
  var indexOfA = order.indexOf(a[0]);
  var aInList = indexOfA >= 0;

  var indexOfB = order.indexOf(b[0]);
  var bInList = indexOfB >= 0;

  // if the first letter of neither string is in the list,
  //  compare alphabetically
  if(!aInList && !bInList) {
    return a.localeCompare(b);
  } else if(!aInList) {
    // the first letter of only a is not in the list
    return 1;
  } else if(!bInList) { 
    // the first letter of only b is not in the list
    return -1;
  } else if(indexOfA === indexOfB) {
    // the first letter of a and b are both in the list
    //  and they are the same
    return a.localeCompare(b);
  } else {
    // the first letters are different; sort by first letter
    return indexOfA - indexOfB;
  }
})

如果您能保证第一个字母在您的排序顺序数组中,您可以省略if(indexOfX === -1)检查。


对于列表中的字母,你可以直接使用return indexOfA - indexOfB;,而不需要使用if语句。 - Michael Antipin
好的,谢谢。我把它写得详细是因为我想明确地展示比较器的工作原理。 - joews
1
哦,还有一件事,如果字母在列表中并且indexOfA == indexOfB,则必须比较字符串本身。否则,以相同字母开头的块将无法排序。 - Michael Antipin
你说得很对,谢谢。我决定采用你的建议,这样阅读起来实际上更容易。 - joews
我不确定为了简洁而省略 a == b 的情况是否是一个好主意。这可能会对大型列表的性能产生影响。 - Michael Antipin
是的 - 实际上在这之前我并不知道 localeCompare。我猜我总是试图在控制台中输入 "str".comp... 进行自动补全,但当我没有找到它时就放弃了。 - joews

0

我不太擅长JS,但这应该对您有用,可能还可以进一步优化。

var outArray = new Array();
var inArray = [ "Zpple", "Zuto", "tim", "tom", "very", "tiolet", "Ztest" ];


inArray.forEach(function(input, i){

    outArray.push(input);
    delete inArray[i];

    var startChar = input.charAt(0);

    inArray.forEach(function(input, i){

        if(input.startsWith(startChar)){
            outArray.push(input);
            delete inArray[i];      
        }       

    });


});

输出:

   ["Zpple", "Zuto", "Ztest", "tim", "tom", "tiolet", "very"]

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