eoao
@eoao

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

複数の条件でソートをする方法

解決したいこと

TypeScriptで以下のリストを以下の条件に従ってソートをしたいです。
よろしくお願いいたします。

1.orderList内のorderNumの昇順でソートする。
 (orderListが空の場合は一番下に入れる)
2.sCodeの昇順にする
3.sCodeが5のもののみpCodeの昇順にする
4.上記の並べ替えを保った状態で、kCodeの昇順に並べ替える

    let list : {
      id: string;
      sCode: string;
      pCode: string;
      kCode: string;
      orderList?: 
        {
          orderNum: number,
          index: number
        }[]
    }[] = [
      {
        id: '1',
        sCode: '5',
        pCode: '100',
        kCode: '5500',
        orderList: [
          {
            orderNum: 2,
            index: 1
          },
          {
            orderNum: 3,
            index: 1
          }
        ]
      },
      {
        id: '2',
        sCode: '5',
        pCode: '100',
        kCode: '5600',
        orderList: []
      },
      {
        id: '3',
        sCode: '6',
        pCode: '101',
        kCode: '5500',
        orderList: [
          {
            orderNum: 2,
            index: 1
          },
          {
            orderNum: 3,
            index: 1
          }
        ]
      },
      // こんな内容のリストが続く…
    ]

自分で試したこと

複数条件でのソートの方法がわからなかったので、
まずlistをループさせてorderListを並び替える。
そのあと、orderListがあるものとないものをfilterで分けてconcatで結合
その後、sCodeでsortをしたのちにsCodeが5のものを抽出して…

のように小分けで何回も抽出して結合する処理を繰り返していました。
この方法だと優先する条件を保ったまま、4の並び替えをすることができないように思っています。

0

2Answer

Array.prototype.sort()があるのですから適当に比較関数を実装してやればよいです.

なおsortは元の配列を破壊するので,状況次第でtoSortedをどうぞ(ES2023以降が必要).

0Like

Comments

  1. @eoao

    Questioner

    Array.prototype.sort()は使用しているのですが、自力で条件を満たす書き方が思いつかなく…。
    大変申し訳ありません。

  2. 1.orderList内のorderNumの昇順でソートする。

    とあるけど、orderListは配列で複数のorderNumが含まれている場合にどうするのか決めないと並び替えられない。

    でもまあ、こんなもんかね。

    list.sort((o1, o2) => {
        if (o1.orderList[0]?.orderNum != o2.orderList[0]?.orderNum) { return (o1.orderList[0]?.orderNum ?? 9999) < (o2.orderList[0]?.orderNum ?? 9999) ? -1 : +1; }
        if (o1.sCode                  != o2.sCode                 ) { return o1.sCode < o2.sCode ? -1 : +1; }
        if (o1.sCode                  == 5                        ) { return o1.pCode < o2.pCode ? -1 : +1; }
        return o1.kCode < o2.kCode ? -1 : +1;
    });
    

Your answer might help someone💌