2016-11-23 7 views
0

アイテムの配列の特定の配列を1つ、生成する配列の識別子を生成することを検討しています。これは決定論的(ランダムではない)でなければなりません。識別子に基づいて配列の特定の順列を生成する

たとえば、3つのアイテムの場合、6つのアレンジがあります。ユーザーがサイトを訪れるたびに、最後に見たものに基づいて選択された1つの特定のアレンジが表示されます。そこブルートフォースによって、可能性の全体のリストを生成する多くの方法がありますが、(「私は注文#1 ['a', 'b', 'c']最後の時間を見たので、この時間は、私に['a', 'c', 'b']あるため#2を示す」)

const items = ['a', 'b', 'c']; 

const possibleArrangements = [ 
    ['a', 'b', 'c'], 
    ['a', 'c', 'b'], 
    ['b', 'a', 'c'], 
    ['b', 'c', 'a'], 
    ['c', 'a', 'b'], 
    ['c', 'b', 'a'], 
]; 

すべての可能な順列を生成することは、このユースケースの場合、識別子に基づいて1つの望ましい配置を得ることが本当に必要な時には過剰です。同じ項目と同じ識別子が与えられると、毎回同じ順列を生成する方法を探しています。

magicFunction(['a', 'b', 'c'], 2)

>> ['b', 'a', 'c']

提案は歓迎されるでしょう。ありがとう!

+0

コレクションが更新されたときにあなただけの順列をキャッシュすることはできません?に答え'magicFunction()'は要求されたインデックスを取得するだけです。最後のものを得るために即座に全ての順列を生成せずに 'magicFunction(['a'、 'b'、 'c']、5)'をどのように取得するのか分かりません。 –

+0

すべての順列のリストをハードコードすることができますが、6項目のリストでは720個のハードコードされた項目です。 (それは速くなります)フロントエンドで可能なアレンジメントのリストが生成され、多くの場合、特定のユーザが最後に見たアレンジをDBに保存するため、キャッシングはありません。 – abought

+1

これがあります:http://stackoverflow.com/questions/7918806/finding-n-th-permutation-without-computing-othersそれでも、必要な順列を得るために*何かを反復する必要があります。多分それはあなたのために働くでしょう。 –

答えて

1

再帰関数を使用します。あなたはすべての可能な配置をしたい場合
は、私は同様の質問herehere

function magicFunction(arr,index){ 
 
    // Finds the number of arrangement possibility starts with a character 
 
    // For example there are 2 arrangement possibility that starts with 'a' 
 
    var partsNum = factorial(arr.length - 1); 
 

 
    // If the index is invalid return undefined 
 
    if (partsNum * arr.length < index + 1 || index < 0){ return; } //Invalid index 
 

 
    // Find the starting character index of the arrangement 
 
    var startIndex = 0; 
 
    while (index + 1 > partsNum){ 
 
     startIndex++; 
 
     index -= partsNum; 
 
    } 
 

 
    // Keeps a reference of the starting character 
 
    var startWith = arr[startIndex]; 
 

 
    arr.splice(startIndex,1); //Removes the character from array 
 
    return startWith + (arr.length > 0 ? magicFunction(arr,index) : ""); 
 
} 
 

 
function factorial(num){ 
 
    var ans = 1; 
 
    while (num > 1){ 
 
     ans *= num; 
 
     num--; 
 
    } 
 
    return ans; 
 
} 
 

 
console.log(magicFunction(['a', 'b', 'c'], 0)); 
 
console.log(magicFunction(['a', 'b', 'c'], 1)); 
 
console.log(magicFunction(['a', 'b', 'c'], 2)); 
 
console.log(magicFunction(['a', 'b', 'c'], 3)); 
 
console.log(magicFunction(['a', 'b', 'c'], 4)); 
 
console.log(magicFunction(['a', 'b', 'c'], 5));

+0

私がこれを正しく読んでいるなら、1つの欠点は、ブルートフォースが必要なものまで少なくともあらゆる配置を計算する必要があることです。これは実現可能かもしれませんが、人々がサイトを深く進んでいくにつれて、訪れた新しいページごとにますます多くの計算が行われます。理想的には、不要な中間作業を回避し、希望する状態に直接進むことができる方法を見つけたいと考えています。 – abought

関連する問題