JavaScriptで配列から特定の値が重複しないグループを作成する方法

Array_Uniqe_Group

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、JavaScriptで配列から特定の値が重複しないグループを作成する方法について解説していきます。

JavaScriptで配列から特定の値が重複しないグループを作成する

個人開発で『ランダムにメンバーを決めるApp(仮)』というSPAアプリをReactで開発しました。

その際の処理のCoreとも言える部分のLogicが「配列から特定の値が重複しないグループを作成する」というものでした。

要件定義

要件定義は、次のようになります。

  1. 名前と部署の名簿情報から、部署別のListを作成する。
  2. 部署別のListからランダムに人員を選択して、グループを作成する。
  3. 各グループの人員(定員)は、選択できる。

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!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

最近の投稿