こんにちはフロントエンドエンジニアのまさにょんです!
今回は、JavaScriptで配列から特定の値が重複しないグループを作成する方法について解説していきます。
目次
JavaScriptで配列から特定の値が重複しないグループを作成する
個人開発で『ランダムにメンバーを決めるApp(仮)』というSPAアプリをReactで開発しました。
その際の処理のCoreとも言える部分のLogicが「配列から特定の値が重複しないグループを作成する」というものでした。
要件定義
要件定義は、次のようになります。
- 名前と部署の名簿情報から、部署別のListを作成する。
- 部署別のListからランダムに人員を選択して、グループを作成する。
- 各グループの人員(定員)は、選択できる。
JavaScriptで配列から特定の値が重複しないグループを作成する
// 1. 名前と部署の名簿情報List
const cardList = [
{id: 1, participant: 'ロボたま', affiliation: 'エンジニア'},
{id: 2, participant: 'まりたま', affiliation: 'エンジニア'},
{id: 3, participant: '白桃', affiliation: '営業部'},
{id: 4, participant: 'ももちゃん', affiliation: '営業部'},
{id: 5, participant: 'まさぴょん', affiliation: '営業部'},
{id: 6, participant: 'まりぴょん', affiliation: 'デザイナー'},
{id: 7, participant: 'ハム太郎', affiliation: 'エンジニア'},
{id: 8, participant: 'ロボ太郎', affiliation: 'デザイナー'},
{id: 9, participant: 'まり太郎', affiliation: 'デザイナー'},
{id: 10, participant: 'ぷる玉', affiliation: '人事部'},
{id: 11, participant: 'ぷるぷる玉', affiliation: '人事部'},
{id: 12, participant: 'ロボ玉試作1号機', affiliation: 'エンジニア'},
{id: 13, participant: 'ロボ玉試作2号機', affiliation: 'デザイナー'},
{id: 14, participant: 'ロボ玉試作1号機', affiliation: 'ロボ玉開発部'},
];
const affiliationList = cardList.map(card => card.affiliation);
console.log('affiliationList', affiliationList);
// 2. 部署だけのListを作成する
const uniqueAffiliList = Array.from(new Set(affiliationList));
console.log('uniqueAffiliList', uniqueAffiliList);
// ['エンジニア', '営業部', 'デザイナー', '人事部', 'ロボ玉開発部']
// 3. 部署別の多次元配列を作成する
const diffAffiliList = []; // 部署別・SeparateList
let sameAffiliList = []; // 同じ部署・List
let len = cardList.length;
uniqueAffiliList.forEach(affili => {
cardList.forEach((card, index) => {
if (affili === card.affiliation ) {
sameAffiliList.push(card);
}
// 最後に、追加して、初期化する
if (len === index + 1) {
diffAffiliList.push(sameAffiliList);
sameAffiliList = [];
}
});
});
console.log('diffAffiliList', JSON.stringify(diffAffiliList));
// 5. 配列の順序をランダムにシャッフルする関数
const shuffleArray = (array) => {
for (let i = array.length - 1; 0 <= i; i--) {
let randomNum = Math.floor(Math.random() * (i + 1));
// 配列の要素の順番を入れ替える
let tmpStorage = array[i];
array[i] = array[randomNum];
array[randomNum] = tmpStorage;
}
}
// 6. 部署ごとに分けられたListの中身の順序をシャッフルする
diffAffiliList.forEach(affiliationArray => {
shuffleArray(affiliationArray);
});
console.log('diffAffiliList', diffAffiliList);
// 7. 部署ごとに分けられたListからグループを作成する
const groupList = [];
let group = [];
let groupingInt = 3;
let affiliationTotal = diffAffiliList.length; // 部署の総数
// 7-1. 部署の総数からIndexListを作成する
let idxList = [];
for (let i = 0; i < affiliationTotal; i++ ) {
idxList.push(i);
}
console.log('idxList', idxList);
// 7-2. 部署が重複しないグループを作成する
diffAffiliList.forEach((affiliList, index, originArray) => {
idxList.forEach(idx => {
// 部署の配列にDataがあれば、先頭を追加、先頭を削除する
let len = originArray[idx].length;
if (len) {
group.push(originArray[idx][0]);
originArray[idx].splice(0, 1);
}
// 指定のグループ人数が集まったら、グループリストに追加する
if (group.length === groupingInt) {
groupList.push(group);
group = []; // 初期化
}
});
// 最後に余ったGroupをSetする => LastかつDataがあればPushする
if (index +1 === affiliationTotal && group.length) groupList.push(group);
});
console.log('groupList', groupList);
JavaScript書籍 Ver. 中級-上級者向け
JavaScript書籍 Ver. 初級者向け
Twitterやってます!Follow Me!
神聖グンマー帝国の逆襲🔥
神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!