LoginSignup
2
2

More than 5 years have passed since last update.

重複ありの組み合わせ作成

Last updated at Posted at 2017-02-19

概要

もう少しシンプルに考えてできそうだと思ったのでやってみた。

  • n進数変換を基に組み合わせを作成。
  • 元の配列を使って、数値を配列要素に変換する。

コード

JS
// 要素の長さと組み合わせ数を基に、n進数列を1文字ずつ配列変換したものを作成。
function getCombArr(len = 2, comb = 1) {
  const num = Math.pow(len, comb),
    makeArr = (v, i) => {
      const n = i.toString(len),
        padStr = '0'.repeat(comb - n.length);
      return (padStr + n).split('');
    };
  return [...Array(num).keys()].map(makeArr);
};

console.log(getCombArr(3, 2)); // [['0','0'],['0','1'],['0','2'],['1','0'],['1','1'],['1','2'],['2','0'],['2','1'],['2','2']]

// 上記関数を利用しつつ、組み合わせを作成
function getComb(arr = [], comb = 1) {
  const base = getCombArr(arr.length, comb),
    convert = v => arr[v],
    makeArr = comb => comb.map(convert);
  return base.map(makeArr);
};

console.log(getComb(['a', 'b', 'c'], 2)); // [['a','a'],['a','b'],['a','c'],['b','a'],['b','b'],['b','c'],['c','a'],['c','b'],['c','c']]

解説

n進数列への変換

3つの要素を2つずつ組み合わせる場合、重複ありで考えると3の2乗で9通り。

const num = Math.pow(len, comb)

数値iをn進数変換する。要素数が3つなら3進数に変換する形となる。
ex. 10進数の3 → 3進数の10, 10進数の8 → 3進数の22

const n = i.toString(len)

最大桁数(組み合わせ数)と同じ桁になるまで0埋めをしつつ、文字列の配列化。
ex. 0"00"["0", "0"]

 padStr = '0'.repeat(comb - n.length);
 return (padStr + n).split('');

組み合わせパターンと同じ要素数の配列を、n進数を基にした配列に変換する。

[...Array(num).keys()].map(makeArr);

元の配列を基に変換する

  1. 上記手順でn進数配列を作成。
  2. 元の配列arr["a", "b", "c"]で、n進数配列内の要素が["0", "1"]であった場合、[arr[0], arr[1]]という形式で変換させ、配列["a", "b"]`を得る。
  3. 上記結果を配列としてまとめる。
function getComb(arr, comb) {
  const base = getCombArr(arr.length, comb),
    convert = v => arr[v],
    makeArr = comb => comb.map(convert);
  return base.map(makeArr);
};

注意点

  • Number.toStringは2~36までしか対応してないため、36個以上の要素数を持つ配列の組み合わせに対応していない。

リンク

2
2
0

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
2