とあるプログラマーの技術ブログ

JavaScriptの配列のソートの話 (2) – lodash _.sortBy()

管理人
6:56 pm

https://blog.ynkb.xyz/296/ の続き。
Array.prototype.sort() は操作が破壊的である点や、柔軟なソートに耐えられないという決定があり、多くの場面では使いづらい。

プリミティブ要素のソート

まずは _.sortBy() から。_.orderBy() はまた次の投稿にて。

nullundefined の扱いは Array の場合と異なる。
null と文字列の 'null' は同一視されない。 nullundefined よりは前に来る。

        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() を確認する予定。

技術情報
%d人のブロガーが「いいね」をつけました。