在javascript中按两个或多个子字符串排序字符串数组

Sort an array of strings by two or more substrings in javascript

本文关键字:字符串 数组 两个 排序 javascript      更新时间:2023-09-26

我有一个javascript数组,看起来像这样:

var data =  ["size64_tolPercent0.01_best", "size256_tolPercent0.01_best", "size256_tolPercent0_worst", "sizemax_tolPercent0_worst", "size1518_tolPercent0_worst", "size64_tolPercent0.01_worst", "size512_tolPercent0.01_worst", "size1518_tolPercent0.01_worst", "size256_tolPercent0_best"] etc

我想对这个数组进行排序:

    通过子字符串"best"answers"worst"。
  1. size (64, 256, 512, 1518, max)..如果大小是按字符串排序的,因为它包含一个"max"关键字。

那么,我们最终得到的结果数组是这样的

["size64_tolPercent0_best", "size256_tolPercent0_best", "size512_tolPercent0_best", "size1518_tolPercent0_best", "sizemax_tolPercent0_best", "size64_tolPercent0.01_best", "size512_tolPercent0.01_best", "size1518_tolPercent0.01_best", "size64_tolPercent0_worst", "size256_tolPercent0_worst", "size512_tolPercent0_worst", "size1518_tolPercent0_worst", "sizemax_tolPercent0_worst"] etc

我可以使用其中一种方法对字符串进行排序,但不能使用所有方法。

这是我到目前为止所尝试的,我确信我做错了,只是需要一些正确方向的帮助。现在为1和3执行:

var someLargeValue = 10000000;
data.sort(function(x,y){
  var xp = x.substr(getPosition(x, '_', 2) + 1, x.split("_").pop().length);
  var yp = y.substr(getPosition(y, '_', 2) + 1, y.split("_").pop().length);
  return xp == yp ? 0 : xp < yp ? -1 : 1;
});
data.sort(function(x,y){
  var xp = x.substr(4, getPosition(x, '_', 1) - 4);
  var yp = y.substr(4, getPosition(y, '_', 1) - 4);
  if(xp === "max") {
    xp = someLargeValue;
  }
  if(yp === "max") {
    yp = someLargeValue;
  }
  xp = parseInt(xp);
  yp = parseInt(yp);
  return xp == yp ? 0 : xp < yp ? -1 : 1;
});
function getPosition(str, m, i) {
    return str.split(m, i).join(m).length;
}

但是我担心我正在尝试的代码是按顺序排序…第一个自定义排序方法会被第二个方法覆盖吗?

非常感谢。

此解决方案的特点是使用来自MDN的映射排序。

首先构建一个带有拆分项的映射数组进行排序。然后按自定义顺序排序。

function (a, b) {
    return a.rating.localeCompare(b.rating) ||
           a.tolPercents - b.tolPercents ||
           a.size - b.size;
}
完全

:

var data = [
        "size64_tolPercent0.01_best",
        "size256_tolPercent0.01_best",
        "size256_tolPercent0_worst",
        "sizemax_tolPercent0_worst",
        "size1518_tolPercent0_worst",
        "size64_tolPercent0.01_worst",
        "size512_tolPercent0.01_worst",
        "size1518_tolPercent0.01_worst",
        "size256_tolPercent0_best"
    ],
    result = data.map(function (el, i) {
        var a = /^size(.+)_tolpercent(.+)_(.+)$/i.exec(el);
        return {
            index: i,
            rating: a[3],
            tolPercents: a[2],
            size: a[1] === 'max' ? Number.MAX_VALUE : a[1]
        };
    }).sort(function (a, b) {
        return a.rating.localeCompare(b.rating) || a.tolPercents - b.tolPercents || a.size - b.size;
    }).map(function (el) {
        return data[el.index];
    });
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

我将首先拆分字符串,以便最小化比较函数完成的工作量,并使其更具可读性。然后,一旦数组被排序,我将重新创建字符串。使用地图更聪明:https://stackoverflow.com/a/32379540/1636522:-D

var data = ["size64_tolPercent0_best", "size256_tolPercent0_best", "size512_tolPercent0_best", "size1518_tolPercent0_best", "sizemax_tolPercent0_best", "size64_tolPercent0.01_best", "size512_tolPercent0.01_best", "size1518_tolPercent0.01_best", "size64_tolPercent0_worst", "size256_tolPercent0_worst", "size512_tolPercent0_worst", "size1518_tolPercent0_worst", "sizemax_tolPercent0_worst"];
// split the strings
var re = /max|'d+(?:'.'d+)?(?=_)|[^_]+$/g;
data = data.map(function (x) {
  x = x.match(re); // example: ["64", "0.01", "best"]
  if (x[0] !== 'max') x[0] = parseInt(x[0], 10);
  x[1] = parseFloat(x[1]);
  return x;
});
// sort the array
data.sort(function cmp (a, b) {
  // 1. "best" and "worst"
  if (a[2] > b[2]) return 1;
  if (a[2] < b[2]) return -1;
  // 2. percent
  if (a[1] > b[1]) return 1;
  if (a[1] < b[1]) return -1;
  // 3. size
  if (a[0] === 'max') return 1;
  if (b[0] === 'max') return -1;
  if (a[0] > b[0]) return 1;
  if (a[0] < b[0]) return -1;
  // 4. no differences
  return 0;
});
// recreate the strings
data = data.map(function (x) {
  x[0] = 'size' + x[0];
  x[1] = 'tolPercent' + x[1];
  return x.join('_');
});
// print the result
data.forEach(function (x) {
  document.write(x + '<br />');
});
* {font-family:Courier}

Array类有一个排序函数:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

利用compare参数:

data.sort(function(a, b) { // Follow the docs as per how a relates to b, returning -1 (a < b),0 (equal) or 1 (a > b) });

根据函数的要求提取子字符串并进行比较。


在阅读了您添加的代码之后,不要调用sort()两次,只需将所有比较合并到相同的排序比较中。在第一个不等式(aValue !== bValue)处停止并返回该比较。