0
0

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 1 year has passed since last update.

【JavaScript】Array.sort()は参照を返す

Last updated at Posted at 2022-12-27

背景

オブジェクト配列をソートするメソッドを作成し、
そのユニットテストを書く。
Jestを利用したユニットテストで、
まずは失敗するように書こうと思った。

ソートするメソッド

function compare (a: Hoge, b: Hoge) {
  if (a.fuga < b.fuga ) {
    return -1
  } else if (a.fuga > b.fuga) {
    return 1
  } else {
    return 0
  }
}

export default (objectList: Hoge[]): Hoge[] => {
  return objectList.sort(compare)
}

ユニットテスト

describe('sort', () => {
  test('false case', () => {
    const baseArray = [ソート元のオブジェクト配列]
    const sortArray = sortMethod(baseArray)
    // ソート順を確認するためループ内で比較
    sortArray.forEach((object, i) => {
       expect(object).toEqual(baseArray[i])
    }
  });
});

しかし、これだとテストが成功してしまった。

原因

Array.sortはソートされた同じ配列の参照を返す
そのためbaseArraysortArrayは参照先が同一となり、
中身はソートされた後の配列になっているため、
テスト結果がtrueになってしまう。

対処

ディープコピーを実施する。
ここではstructuredClone()を使用する。
(使用できない環境であればJSON.parse(JSON.stringfy())を使用するといい)

describe('sort', () => {
  test('false case', () => {
    const baseArray = [ソート元のオブジェクト配列]
    // ソート結果をディープコピーする
    const deepCopySortArray = structuredClone(sortMethod(baseArray))
    deepCopySortArray.forEach((object, i) => {
       expect(object).toEqual(baseArray[i])
    }
  });
});

これでテストが失敗することが確認できた。

結論

Array.sort()参照を返すため、それを意識して使用すること。

参考

Array.prototype.sort()
Deep copy (ディープコピー)

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?