LoginSignup
2
0

More than 3 years have passed since last update.

多段階ソートを書きやすい記載で動作するように実装する

Last updated at Posted at 2020-11-01

やめ太郎先生のところで、lodash の多段階のソートが紹介されていました。

ワイ「なに!?ライブラリをラップするやと!?」 - Qiita
https://qiita.com/Yametaro/items/111ce26637d6a3c2e763


const userList = [
  {
    name: 'c',
    age: 20,
  },
  {
    name: 'b',
    age: 20,
  },
  {
    name: 'a',
    age: 20,
  },
  {
    name: 'c',
    age: 21,
  },
];

const sortedUserList = _.orderBy(userList, ['name', 'age'], ['asc', 'desc'])
console.log(sortedUserList)

// [[object Object] {
//   age: 20,
//   name: "a"
// }, [object Object] {
//   age: 20,
//   name: "b"
// }, [object Object] {
//   age: 21,
//   name: "c"
// }, [object Object] {
//   age: 20,
//   name: "c"
// }]

パラメータ指定によって項目内部のnameとageで、降順、昇順が指定できるようになっているようです。

sort関数は書いたことがあったのですが、複数条件でのソートを考慮するのを忘れていました。

partsjs/array.test.js at v9.0.0 · standard-software/partsjs
https://github.com/standard-software/partsjs/blob/v9.0.0/source/array/array.test.js#L2385

複数条件でのソートは普通、いろんな場面で使いそうなので実装してみました。

const orderFuncFromName = name => {
  if (name === 'asc') {
    return (a, b) => (
      a > b ? 1
      : a < b ? -1
      : 0
    );
  } else {
    return (a, b) => (
      a > b ? -1
      : a < b ? 1
      : 0
    );
  }
}

const sort = (array, orderFuncs) => {
  const orderFuncArray = [];
  for (const [orderName, func] of orderFuncs) {
    const orderFunc = orderFuncFromName(orderName);
    orderFuncArray.push((a, b) => orderFunc(func(a), func(b)));
  }
  array.sort((a, b) => {
    for (const orderFuncItem of orderFuncArray) {
      const result = orderFuncItem(a, b);
      if (result !== 0) {
        return result;
      }
    }
    return 0;
  });
};

const sortedUserList = [...userList];
sort(sortedUserList, [
  ['asc', v => v.name],
  ['desc', v => v.age],
]);

console.log(sortedUserList)

思った以上にわかりやすく短めに書けました。

これで項目内の文字列の内容や長さや数値でのソートが書きやすくなりそう。

2
0
3

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
0