Edited at

月~土までで各曜日担当を割り振るっていうもんだから、ランダムで担当割り振る関数作ってみた。

More than 1 year has passed since last update.

JavaScript Advent Calendar 2017 9日目の記事です。


(ある日のこと)担当者がいなくなった

システムが属人化してしまうのは、IT業界ではよくあることなのかなと思います。

ここではシステムというわけではないのですが、行われていた業務(の一部)がほぼ一人で回されていたため、その方がいなくなり、やってもらってた仕事が回らなくなってしまったので、各曜日に担当をつけて、毎日その人に処理してもらうことになりました(※属人化脱出とかそういう話じゃありません)。

となると、問題は誰が何曜日にやるのか。

休みも皆が意外に不定休で休むし、月末や週末が処理する量が多かったり、週半ばはあまりないなど、日によって忙しさの変動する仕事...。

そりゃ、誰だって楽したい!

俺はこの曜日がいい!っと普通に喧嘩になるのは目に見えてました(そんなわけない)。


人類は何世紀も前に、公正な方法を生み出していた。

その名もあみだくじ。


あみだくじ(阿弥陀籤)とは...線のはしに当たりはずれなどを書いて隠し、各自が引き当てるくじのこと。現在は、平行線の間に横線を入れ、はしご状にすることが多い。もともとは、人数分の線を引き、一端にそれぞれ異なる金額を書いて隠し、各自が引き当てた金額を出させ、集めた金で茶菓子などを買い、平等に分配する仕組みだった。現在では、用途は広がっており、何かの順番を決めたり、何かで言い争った場合に○を引き当てた方が勝ちとしたりして、幅広く利用されている。(wikipedia引用)


えっ!?

そう紙に書いて名前つけてやるあれ。

でも、私は今をときめくITベンチャーで働く、名ばかりでもエンジニア。

ただ、神に祈るなんて柄じゃない。

神に祈るな。コードに祈れ。


まずはプロトタイプ的な...?

というわけであみだくじ的に曜日を割振るようにしました。


random.js


let member = ['A','B','C','D','E','F'];
function setRandom(mem) {
// ランダム数を作る
function getRandom() {
let r = Math.floor(Math.random()*10);
if (r>=6) {
return getRandom();
} else {
return r;
}
}
let re = [];
for (let i = 0; i < 6;) {
let num = getRandom();
if (re.indexOf(num) !== -1) {
continue;
} else {
re[mem[i]] = num;
if (re.length === 6)
break;
i++;
}
}
return re;
}
// console.log(setRandom(member));


は?って感じで草生えますね。

まあ、こんな感じでまずは各人(A〜F)に対し、各曜日(1〜6)を割振るところから始めてはみました。。


紆余曲折あったものの以下に落ち着く

1~6の乱数作るの、そのやり方だとスゲー時間かかってる...。

→割となんとかして、作ってみるという習慣がついているせいか、6以下のランダム数を作るのにこんなことしちゃいました。

数字出力とか曜日いつだよ?

せめて「曜日:人物」くらいの表記はしないと見にくい。

これ、名前に数字入るとアウトだ...。

...

...

などなど、、まだいろいろできそうなのでとりあえず修正。


Ghostleg.js

class Ghostleg {

constructor (member, days, mM) {
this.member = member;
this.days = days;
this.min = mM.min;
this.max = mM.max;
this.weekStr = [ "", "", "", "", "", "", "" ];
}
getRandom() {
return Math.floor(Math.random() * (this.max - this.min + 1)) + this.min;
}
setNumberToMember(r) {
// メンバー数と数値数が一致しなければ終了
if (this.member.length !== r.length) return null;
let returnArray = {},
k = 0;
// 各メンバーに対して曜日を割り当てる
for (let a in this.member) {
returnArray[this.member[a]] = this.weekStr[r[k]];
k++;
}
this.ghostleg = this.swap(returnArray);
}
swap (arr) {
let ret = {};
for (let key in arr) {
ret[arr[key]] = key;
}
return ret;
}
weekSort (unsortedObj) {
// 曜日順列で取得
const sortedKeys = Object.keys(unsortedObj).sort((a, b) => this.weekStr.indexOf(a) > this.weekStr.indexOf(b));
let returnObj = {};
// 曜日順でconsoleに対象者を出力するだけ
sortedKeys.forEach((key) => {
// このconsoleはただの出力用
console.log(key,':',unsortedObj[key]);
if (key !== 'undefined')
returnObj[key] = unsortedObj[key];
});
return returnObj;
}
main () {
let re = [];
for (let i = 0; i < this.days;) {
// min,Max間での数を取得し、重複しなければ格納する
let num = this.getRandom();
if (re.indexOf(num) !== -1) {
continue;
} else {
re[i] = num;
if (re.length === 6) {
this.setNumberToMember(re);
break;
}
i++;
}
}
}
}

const member = ['A','B','C','D','E','F'];
let amida = new Ghostleg(member, 6, {min:1, max:6});
amida.main();
amida.weekSort(amida.ghostleg);


別にクラスにしたのは特に意味はないです。

普通に関数で書いていたのですが、書いててノってきたのと書く機会がなかったので、ちょっとやってみたかっただけです(全然よくわからんし、無駄にコード長くした気もする)。

結局めんどくさくて数字対応やってない、、

コンソールに表示するのもなんかあれだし、オブジェクトだからわざわざ表示の為だけにソートするのも処理で考えると非常に無駄(機能としては必要なんですけども)

実際に利用すると、何も考えずに決まるから助かる(まあ、なにも考えなくていいので)的には言われますが、同姓同名がいた場合はアウトなので改良の必要ありですし、まだまだ感あります。

そして、、そもそもなんでJSで書いた(あと第二引数...)?


まとめ

システム会社でも、社内のシステム(そんな大それたもんじゃないですが)を作るとかってあまりないので、個人的には楽しかったです(練度は低いですが)。

こういう取り組みが社内ハッカソンやイベント事への足がかりにできれば、よい文化を生める気がするので、遊び心を持って開発をこれからも行っていきたいです。

とりあえずは、これをさらに進化させて、グラフィックなんかもつけて、viewに表示できるようにしていくと楽しいなという感じですので、冬休みにはこれをスマホアプリに昇華(さらにもう少しちゃんとあみだくじっぽくして)するだとか、グーグルカレンダーなんかに月単位で登録したりできるとより便利になる気がするので頑張りたいと思います。

もし、なにか改修ポイント等があれば、担当者(僕ではなく)が喜びますので、頑張りたいと思います。

以上、JavaScript Advent Calendar 2017の9日目でした。

10日目の方よろしくお願いいたします!


参考

Math.random()

バラバラの曜日を曜日順にソートする方法

あみだくじ