对字符串数组进行排序,其中大写首先包含重音

时间:2019-05-22 08:59:33

标签: javascript arrays string sorting

所以我在互联网上徘徊,寻找js中的排序功能。这是问题所在。 我们有一个像这样的字符串数组:

['único', 'UNICO', 'árbol', 'ARBOL', 'cosas', 'COSAS', 'fútbol', 'FUTBOL']

我们想要这样的东西(大写优先):

['ARBOL', 'COSAS', 'FUTBOL', 'UNICO', 'árbol', 'cosas', 'fútbol', 'único']

或这样(小写优先):

['árbol', 'cosas', 'fútbol', 'único', 'ARBOL', 'COSAS', 'FUTBOL', 'UNICO']

问题是:真的很容易做到这一点:

['ARBOL', 'COSAS', 'FUTBOL', 'UNICO', 'cosas', 'fútbol', 'árbol','único']

具有.sort();函数,但我们不希望在结尾使用重音词,因此我们使用

.sort(function(a, b) {
  return a.localCompare(b);
});

但是我们最终得到了这个...

['ARBOL', 'árbol', 'COSAS', 'cosas', 'FUTBOL', 'fútbol', 'UNICO', 'único']

你们对如何将两者结合有任何想法吗?

5 个答案:

答案 0 :(得分:4)

您可以简单地扩展sort函数以在字符串的开头优先考虑大写字符:

const arr = ['ÁRBOL', 'único', 'UNICO', 'árbol', 'ARBOL', 'cosas', 'COSAS', 'fútbol', 'FUTBOL'];

function startsWithUppercase(str) {
    return str.substr(0, 1).match(/[A-Z\u00C0-\u00DC]/);
}

arr.sort(function(a, b) {
    if (startsWithUppercase(a) && !startsWithUppercase(b)) {
        return -1;
    } else if (startsWithUppercase(b) && !startsWithUppercase(a)) {
        return 1;
    }
    return a.localeCompare(b);
});

console.log(arr);

答案 1 :(得分:2)

我不认为仅凭localeCompare就有可能,请参见:

How to get localeCompare to behave similarly to .sort(), so that all capital letters come first?

但是您可以将heresort结合使用:

const arr = ['único', 'UNICO', 'árbol', 'ARBOL', 'cosas', 'COSAS', 'fútbol', 'FUTBOL'];
const norm = str => str.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
arr.sort((a, b) => Number(norm(a) > norm(b)) || -(Number(norm(b) > norm(a))));
console.log(arr);
// ['ARBOL', 'COSAS', FUTBOL', 'UNICO', 'árbol', 'cosas', 'fútbol', 'único']

答案 2 :(得分:1)

排序数组,如果:

  1. a均为大写或小写,请通过localeCompare对它们进行排序。
  2. 如果只有a是大写字母,则a应该为1(返回-1)。
  3. 默认值(仅b为大写)首先为b(返回1)。

注意:这是假设所有单词都没有大小写混合的字母。

const arr = ['único', 'UNICO', 'árbol', 'ARBOL', 'cosas', 'COSAS', 'fútbol', 'FUTBOL']

arr.sort((a, b) => {
  const aIsUpperCase = a.toUpperCase() === a;
  const bIsUpperCase = b.toUpperCase() === b;
  
  if(aIsUpperCase === bIsUpperCase) return a.localeCompare(b, 'es');
  
  if(aIsUpperCase) return -1;
  
  return 1;
})

console.log(arr)

答案 3 :(得分:0)

您可以按大小写将它们拆分,将每个排序然后放回一起。

let foo = ['único', 'UNICO', 'árbol', 'ARBOL', 'cosas', 'COSAS', 'fútbol', 'FUTBOL'];
foo = foo.reduce((a, b) => {
    b.toUpperCase() === b ? a[0].push(b) : a[1].push(b);
    return a;
}, [[],[]]).flatMap(e => e.sort((a, b) => a.localeCompare(b)));

console.log(foo);

答案 4 :(得分:0)

您可以使用map进行排序,并根据情况在字符前面或后面留一个空格,将每个字符替换为两个字符。然后排序并映射一个新数组。

  

示例

     

未排序

val f1: Int => Int = _ + 1
val f2: Int => Int = _ + 2
val f3: Int => Int = _ + 3

val fx: Int => (Int, Int) = i => (i + 4, i + 5)

// let's assume that the original fy simply sums up its two parameters
val fyp: (Int => Int) => ((Int, Int)) => Int =
  f => fyArgs => f(fyArgs._1) + fyArgs._2

val composed1 = f1 andThen f2 andThen f3
println(composed1(42)) // 48

val composed2 = f1 andThen f2 andThen fx andThen fyp(f3)
println(composed2(42)) // 102

// because:
// f1 -> f2 -> fx = (42 + 1 + 2 + 4, 41 + 1 + 2 + 5) = (49, 50)
// fyp(f3)((49, 50)) = (49 + 3) + 50 = 102    
     

已排序

index  value
-----  --------------------
   0   'ú   n  i  c  o '
   1   '  U  N  I  C  O'
   2   'á   r  b  o  l '
   3   '  A  R  B  O  L'
   4   ' c  o  s  a  s '
   5   '  C  O  S  A  S'
   6   ' f ú   t  b  o  l '
   7   '  F  U  T  B  O  L'

index  value
-----  --------------------
   3   '  A  R  B  O  L'
   5   '  C  O  S  A  S'
   7   '  F  U  T  B  O  L'
   1   '  U  N  I  C  O'
   4   ' c  o  s  a  s '
   6   ' f ú   t  b  o  l '
   2   'á   r  b  o  l '
   0   'ú   n  i  c  o '
var array = ['único', 'UNICO', 'árbol', 'ARBOL', 'cosas', 'COSAS', 'fútbol', 'FUTBOL'],
    result = array
        .map((s, index) => ({ index, value: Array.from(s, c => c === c.toUpperCase()
            ? '  ' + c
            : c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'
                ? ' ' + c + ' '
                : c + '  '
        ).join('') }))
        .sort((a, b) => a.value.localeCompare(b.value))
        .map(({ index }) => array[index]);

console.log(result);