
JavaScriptの配列のソートの話 (2) – lodash _.sortBy()
https://blog.ynkb.xyz/296/ の続き。Array.prototype.sort()
は操作が破壊的である点や、柔軟なソートに耐えられないという決定があり、多くの場面では使いづらい。
プリミティブ要素のソート
まずは _.sortBy()
から。_.orderBy()
はまた次の投稿にて。
null
と undefined
の扱いは Array
の場合と異なる。null
と文字列の 'null'
は同一視されない。 null
は undefined
よりは前に来る。
it('nullとundefinedの扱い', () => {
// Arrange
const array = [undefined, null, 'undefined', 'null', 'test'];
// Act
const sorted = _.sortBy(array);
// Assert
expect(sorted).toEqual(['null', 'test', 'undefined', null, undefined]);
});
Array
と違って数値をソートできる。
it('数値の配列をソートできる', () => {
// Arrange
const array = [1, 0, 2, -1, 11];
// Act
const sorted = _.sortBy(array);
// Assert
expect(sorted).toEqual([-1, 0, 1, 2, 11]);
});
数値と文字列が混在していたら、数値のほうが先にくるようだ。
it('数値と文字列が混合してたら?', () => {
// Arrange
const array = [1, 0, 2, -1, 11, '12', '2'];
// Act
const sorted = _.sortBy(array);
// Assert
expect(sorted).toEqual([-1, 0, 1, 2, 11, '12', '2']);
});
オブジェクトのソート
次に以下のオブジェクト配列をソートしてみる。
const users = [
{'user': 'fred', 'age': 48},
{'user': 'barney', 'age': 36},
{'user': 'fred', 'age': 40},
{'user': 'barney', 'age': 34},
]
簡単なのは、ソートに使うプロパティ名を配列で指定するやり方。
it('_.sortBy()でソートできる', () => {
// Act
const sortedUsers = _.sortBy(users, ['user', 'age']);
// Assert
expect(sortedUsers).toEqual([
{'user': 'barney', 'age': 34},
{'user': 'barney', 'age': 36},
{'user': 'fred', 'age': 40},
{'user': 'fred', 'age': 48},
])
});
要素同士の大小比較に使う値を返却する関数を渡すやり方もある。
it('_.sortBy()でソートできる2', () => {
// Act
const sortedUsers = _.sortBy(users, u => u.user);
// Assert
expect(sortedUsers).toEqual([
{'user': 'barney', 'age': 36},
{'user': 'barney', 'age': 34},
{'user': 'fred', 'age': 48},
{'user': 'fred', 'age': 40},
])
});
関数で以下のように配列を返却するようにすれば、最初の例と等価である。
it('_.sortBy()でソートできる3', () => {
// Act
const sortedUsers = _.sortBy(users, u => [u.user, u.age]);
// Assert
expect(sortedUsers).toEqual([
{'user': 'barney', 'age': 34},
{'user': 'barney', 'age': 36},
{'user': 'fred', 'age': 40},
{'user': 'fred', 'age': 48},
])
});
次回は _.orderBy()
を確認する予定。