J'ai vu plusieurs questions similaires sur la façon de générer toutes les combinaisons possibles d'éléments dans un tableau. Mais j'ai beaucoup de mal à comprendre comment écrire un algorithme qui ne produira que des combinaisons paires . Toutes les suggestions seraient super appréciées!
Commençant par le tableau suivant (avec N éléments):
var array = ["Apple", "banana", "lemon", "mango"];
Et en obtenant le résultat suivant:
var result = [
"Apple banana"
"Apple lemon"
"Apple mango"
"banana lemon"
"banana mango"
"lemon mango"
];
J'essayais l'approche suivante, mais cela aboutit à toutes les combinaisons possibles, mais uniquement à des paires de combinaisons.
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);
}
}
Un moyen simple serait de faire une double boucle for sur le tableau où vous sautez les premiers éléments i
de la seconde boucle.
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);
Réécrit avec 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);
Voici deux programmation fonctionnelle solutions 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);
Ou:
var array = ["Apple", "banana", "lemon", "mango"];
var result = [].concat(...array.map(
(v, i) => array.slice(i+1).map( w => v + ' ' + w ))
);
console.log(result);
Bien que des solutions aient été trouvées, je publie ici un algorithme permettant de trouver toutes les combinaisons taille n
de m (m>n)
éléments. Dans votre cas, nous avons n=2
et 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);
Générer des combinaisons d'éléments dans un tableau ressemble beaucoup à compter dans un système numérique, Où la base correspond au nombre d'éléments de votre tableau (si vous tenez compte des zéros qui seront manquants).
Cela vous donne tous les indices de votre tableau (concaténés):
arr = ["Apple", "banana", "lemon", "mango"]
base = arr.length
idx = [...Array(Math.pow(base, base)).keys()].map(x => x.toString(base))
Vous n'êtes intéressé que par paires de deux, alors restreignez la plage en conséquence:
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.
Reste maintenant à mapper les index sur les valeurs.
Comme vous ne voulez pas que les éléments soient associés à eux-mêmes et que l'ordre n'ait pas d'importance, il faut supprimer ceux-ci avant de les mapper au résultat final.
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"]))
Avec plus de dix éléments, toString()
renverra des lettres pour les index; De plus, cela ne fonctionnera qu'avec 36 éléments maximum.
Essayez ceci: 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]);
}
map
et flatMap
permettent d'effectuer les opérations suivantes (flatMap
est uniquement pris en charge sur chrome et firefox
var array = ["Apple", "banana", "lemon", "mango"]
array.flatMap(x => array.map(y => x !== y ? x + ' ' + y : null)).filter(x => x)