2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[JavaScript] 文字列のアルファベット大小文字考慮した辞書順ソート

Last updated at Posted at 2020-09-09

アルファベット順、大文字小文字無視したソート

次のようなコードがよく紹介されていました。

var source = ['a', 'B', 'A', 'b', 'aa', 'Aa', 'AA', 'aA', 'aB', 'ab', 'Ab', 'AB']
source.sort((a, b) => {
  a = a.toLowerCase();
  b = b.toLowerCase();
  if (a < b) {
    return -1;
  } else if (a > b) {
    return 1;
  }
  return 0;
})
console.log(source);
// [ 'a', 'A', 'AA', 'aA', 'aa', 'Aa', 'aB', 'ab', 'Ab', 'AB', 'B', 'b' ]

このコードだとある程度は文字列を並び替えられるのですが、大文字と小文字は同一視されているので、どちらかが優先されることがないです。

いわゆる辞書順を考えると、大文字を優先するか、小文字を優先するか、を判断したいところ。

アルファベット順、大文字、小文字、優先順位をつける。

次のようにします。

var source = ['a', 'B', 'A', 'b', 'aa', 'Aa', 'AA', 'aA', 'aB', 'ab', 'Ab', 'AB']
source.sort((a, b) => {
  const la = a.toLowerCase();
  const lb = b.toLowerCase();
  if (la < lb) {
    return -1;
  } else if (la > lb) {
    return 1;
  } else {
    for(let i = 0, l = a.length; i < l; i += 1) {
      if (a[i] < b[i]) {
        return -1;
      }
      if (b[i] < a[i]) {
        return 1
      }
    }
  }
})
console.log(source);
// [ 'A', 'a', 'AA', 'Aa', 'aA', 'aa', 'AB', 'Ab', 'aB', 'ab', 'B', 'b' ]

アルファベット順で、大小文字区別なしで同一文字の場合には、1文字ごとに並び順を判定するとよいです。

小文字優先にしたい場合は、for の内部の、-1 と 1 を入れ替えるとよいです。

// [ 'a', 'A', 'aa', 'aA', 'Aa', 'AA', 'ab', 'aB', 'Ab', 'AB', 'b', 'B' ]

追記:アルファベット順、大文字、小文字、優先順位をつける。

より効率よいコードを、コメント欄で @sugoroku_y さんに教えていただきました。ありがとうございます!

このように書いても同じ結果が出力されます。

var source = ['a', 'B', 'A', 'b', 'aa', 'Aa', 'AA', 'aA', 'aB', 'ab', 'Ab', 'AB']
source.sort((a, b) => {
  const la = a.toLowerCase();
  const lb = b.toLowerCase();
  if (la < lb) {
    return -1;
  } 
  if (la > lb) {
    return 1;
  } 
  if (a < b) {
    return -1;
  }
  if (b < a) {
    return 1
  }
})
console.log(source);
// ["A", "a", "AA", "Aa", "aA", "aa", "AB", "Ab", "aB", "ab", "B", "b"]

var source = ['a', 'B', 'A', 'b', 'aa', 'Aa', 'AA', 'aA', 'aB', 'ab', 'Ab', 'AB']
const sorted = source.map(
  s => ({o: s, l: s.toLowerCase()})
).sort((a, b) => {
  if (a.l < b.l) return -1;
  if (a.l > b.l) return 1;
  if (a.o < b.o) return -1;
  if (a.o > b.o) return 1;
  return 0;
}).map(e => e.o)
console.log(sorted)
// ["A", "a", "AA", "Aa", "aA", "aa", "AB", "Ab", "aB", "ab", "B", "b"]

JS Bin で動かせるコードを載せました。
https://jsbin.com/busucecotu/2/edit?html,js,console

2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?