【问题标题】:Javascript sort array of words ignoring first wordJavascript排序单词数组忽略第一个单词
【发布时间】:2020-08-07 15:26:13
【问题描述】:

我有一组单词,如下所示:

arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"]

我想对其进行排序,但忽略了第一个单词。例如,输出将是:

arr = ["id-3 abc home", "id1 abc test", "id#2 XX car house"]

谢谢

【问题讨论】:

  • 这里的排序规则是什么?请更清楚
  • 按字典顺序排序,忽略第一个单词。在示例中,“id1”、“id-3”和“id#2”在排序中不应考虑
  • 那么您在排序时是否考虑了 unicode 代码点?仍然不确定规则
  • 为什么id1 abc testid-3 abc home之前?
  • 对不起,id-3 abc home 应该在之前

标签: javascript arrays string sorting


【解决方案1】:

您可以使用 array.sort 从字符串中搜索空格的索引,然后从空格后的一个位置与原始字符串进行比较。

备注: 为了实现排序功能,您需要注意 (a,b) 有 3 个不同的返回值:

  • 返回:< 0 => a
  • 返回:= 0 => a=b
  • 返回:< 0 => a>b

结果在我考虑后现在可以了(我在这里犯了一个错误,现在已更正):
"id#2 XX car house", "id-3 abc home", "id1 abc test"
注意: XX 位于 abc 之前,因为大写字母小于小写字母,例如来自“A”的 ASCII 是 65,来自“a”的 ASCII 是 97。

console.log('A'.charCodeAt(0));
console.log('a'.charCodeAt(0));

这里是扩展版中的代码示例,因为是否要考虑对大写/小写问题进行排序并没有 100% 明确。所以我添加了一个额外的参数,所以现在两种变体都是可能的:

let arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"];

function specialSort(ignoreUpperCase) {
    arr.sort( (a,b) => {
        if (ignoreUpperCase) {
            a = a.toUpperCase();
            b = b.toUpperCase()
        }
        a = a.substr(a.indexOf(' ')+1);
        b= b.substr(b.indexOf(' ')+1);
        return (a<b) ? -1 : (a>b) ? 1 : 0;
   });
}

specialSort(true);
console.log('Ignore UpperCases:',arr);

specialSort(false);
console.log('With UpperCases:',arr);

【讨论】:

  • 您好,它不会对具有相同第二个单词的那些进行排序。在示例中,id-3 abc home 应位于 id1 abc test 之前
  • @myTest532 myTest532 你说得对,我对排序函数的返回值犯了一个错误。但是你弄错了结果,它是:"id#2 XX car house", "id-3 abc home", "id1 abc test" 因为 X
  • @ Peter Seliger OP想要从第二个单词的开头到字符串的结尾对其进行排序。如果不考虑大写/小写,他就没有什么想要排序的,所以他的结果是错误的,或者他必须指定更多。
  • @Peter Seliger 我在 20 分钟前编辑过,是的(这是在你说话之前)。我没有做错什么。因为OP本身批准了它,所以没关系。如果没有得到 OP 的批准,我无法在此处编辑任何内容我没有足够的声誉..
  • @ Peter Seliger 我扩展了对这两种变体的排序,因此 OP 可以自己决定他更喜欢哪一种。我看到您将问题重新编辑为最新版本。没关系(因为 OP 批准了它),但我更喜欢这个问题,而不是大写/小写无关紧要的问题。但我不想为此吵架。
【解决方案2】:

function getStringWithoutFirstWord(str) {
  return str.split(/\s+/).slice(1).join(' ');
}

function compareLoacallyWhilstIgnoringFirstWord(a, b) {
  a = getStringWithoutFirstWord(a); // yes, this is a ...
  b = getStringWithoutFirstWord(b); // ... highly repetitive task.
  return a.localeCompare(b);
}
function compareStronglyAscendingWhilstIgnoringFirstWord(a, b) {
  a = getStringWithoutFirstWord(a);  // yes, this is a ...
  b = getStringWithoutFirstWord(b); // ... highly repetitive task.
  return ((a < b && -1) || (a > b && 1) || 0);
}

const arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"];


console.log(
  arr.sort(compareLoacallyWhilstIgnoringFirstWord)
);
console.log(
  arr.sort(compareStronglyAscendingWhilstIgnoringFirstWord)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

... Hassan Imam 提到的decorate-sort-undecorate 方法的工作实现...

function getStringWithoutFirstWord(str) {
  return str.split(/\s+/).slice(1).join(' ');
}

function restoreStringFromDecoratedIgnoredFirstWordData(data) {
  return data.original;
}
function createDecoratedIgnoredFirstWordData(str) {
  return {
    original: str,
    sortable: getStringWithoutFirstWord(str)
  }
}

function compareSortablesLoacally(a, b) {
  return a.sortable.localeCompare(b.sortable);
}
function compareSortablesStronglyAscending(a, b) {
  a = a.sortable;
  b = b.sortable;
  return ((a < b && -1) || (a > b && 1) || 0);
}

const arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"];


console.log(arr
  .map(createDecoratedIgnoredFirstWordData)
  .sort(compareSortablesLoacally)
  .map(restoreStringFromDecoratedIgnoredFirstWordData)
);

console.log(arr
  .map(createDecoratedIgnoredFirstWordData)
  .sort(compareSortablesStronglyAscending)
  .map(restoreStringFromDecoratedIgnoredFirstWordData)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

【讨论】:

    【解决方案3】:

    这可以通过常规的Array.prototype.sort 和一个忽略第一个单词的小正则表达式来完成:

    const arr = ["id1 abc test", "id#2 XX car house", "id-3 abc home"]
    
    const result = arr.sort((a,b) => {
    
      const [aStr, bStr] = [a,b].map(l => l.replace(/^\S+/g,''));
    
      return aStr.localeCompare(bStr)
    
    })
    
    console.log(result);

    【讨论】:

    • 谢谢。没有正则表达式可以吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2015-12-10
    • 2021-03-14
    相关资源
    最近更新 更多