配列内の要素のすべての可能な組み合わせを生成する方法について、いくつかの同様の質問を見てきました。しかし、組み合わせpairsのみを出力するアルゴリズムを作成する方法を見つけるのは非常に困難です。どんな提案でも大歓迎です!
次の配列(N要素)から開始します。
var array = ["Apple", "banana", "lemon", "mango"];
そして、次の結果を取得します。
var result = [
"Apple banana"
"Apple lemon"
"Apple mango"
"banana lemon"
"banana mango"
"lemon mango"
];
私は次のアプローチを試していましたが、これはすべての可能な組み合わせになり、代わりに組み合わせのペアのみになります。
var letters = splSentences;
var combi = [];
var temp= "";
var letLen = Math.pow(2, letters.length);
for (var i = 0; i < letLen ; i++){
temp= "";
for (var j=0;j<letters.length;j++) {
if ((i & Math.pow(2,j))){
temp += letters[j]+ " "
}
}
if (temp !== "") {
combi.Push(temp);
}
}
簡単な方法は、2番目のループで最初のi
要素をスキップする配列に対してdouble forループを実行することです。
let array = ["Apple", "banana", "lemon", "mango"];
let results = [];
// Since you only want pairs, there's no reason
// to iterate over the last element directly
for (let i = 0; i < array.length - 1; i++) {
// This is where you'll capture that last value
for (let j = i + 1; j < array.length; j++) {
results.Push(`${array[i]} ${array[j]}`);
}
}
console.log(results);
ES5で書き直されました:
var array = ["Apple", "banana", "lemon", "mango"];
var results = [];
// Since you only want pairs, there's no reason
// to iterate over the last element directly
for (var i = 0; i < array.length - 1; i++) {
// This is where you'll capture that last value
for (var j = i + 1; j < array.length; j++) {
results.Push(array[i] + ' ' + array[j]);
}
}
console.log(results);
2つの機能プログラミング ES6ソリューションがあります。
var array = ["Apple", "banana", "lemon", "mango"];
var result = array.reduce( (acc, v, i) =>
acc.concat(array.slice(i+1).map( w => v + ' ' + w )),
[]);
console.log(result);
または:
var array = ["Apple", "banana", "lemon", "mango"];
var result = [].concat(...array.map(
(v, i) => array.slice(i+1).map( w => v + ' ' + w ))
);
console.log(result);
解決策は見つかりましたが、ここでは一般的な場合のサイズn
of m (m>n)
要素を見つけるための一般的なアルゴリズムを投稿します。あなたの場合、n=2
およびm=4
。
const result = [];
result.length = 2; //n=2
function combine(input, len, start) {
if(len === 0) {
console.log( result.join(" ") ); //process here the result
return;
}
for (var i = start; i <= input.length - len; i++) {
result[result.length - len] = input[i];
combine(input, len-1, i+1 );
}
}
const array = ["Apple", "banana", "lemon", "mango"];
combine( array, result.length, 0);
map
およびflatMap
を使用すると、次のことができます(flatMap
は chromeおよびfirefox でのみサポートされます)
var array = ["Apple", "banana", "lemon", "mango"]
array.flatMap(x => array.map(y => x !== y ? x + ' ' + y : null)).filter(x => x)
配列内の要素の組み合わせの生成は、数値システムでのカウントによく似ています。ここで、基数は配列内の要素の数です(欠落している先行ゼロを考慮した場合)。
これにより、配列へのすべてのインデックスが得られます(連結されます)。
_arr = ["Apple", "banana", "lemon", "mango"]
base = arr.length
idx = [...Array(Math.pow(base, base)).keys()].map(x => x.toString(base))
_
2つのペアのみに関心があるため、それに応じて範囲を制限します。
_range = (from, to) = [...Array(to).keys()].map(el => el + from)
indices = range => range.map(x => x.toString(base).padStart(2,"0"))
indices( range( 0, Math.pow(base, 2))) // range starts at 0, single digits are zero-padded.
_
あとは、インデックスを値にマップするだけです。
要素をそれ自体とペアにしたくないし、順序は関係ないので、最終結果にマッピングする前に、それらを削除する必要があります。
_const range = (from, to) => [...Array(to).keys()].map(el => el + from)
const combinations = arr => {
const base = arr.length
return range(0, Math.pow(base, 2))
.map(x => x.toString(base).padStart(2, "0"))
.filter(i => !i.match(/(\d)\1/) && i === i.split('').sort().join(''))
.map(i => arr[i[0]] + " " + arr[i[1]])
}
console.log(combinations(["Apple", "banana", "lemon", "mango"]))
_
10個以上の要素がある場合、toString()
はインデックスの文字を返します。また、これは最大36個の要素でのみ機能します。
これを試してください: https://jsfiddle.net/e2dLa9v6/
var array = ["Apple", "banana", "lemon", "mango"];
var result = [];
for(var i=0;i<array.length-1;i++){
for(var j=i+1;j<array.length;j++){
result.Push(array[i]+" "+array[j]);
}
}
for(var i=0;i<result.length;i++){
alert(result[i]);
}