私は次のようなオブジェクトの配列を持っています:複数の配列要素をインデックス間で効率的にランダム化する方法はありますか?
各エントリはその配列内のオブジェクトです。私がする必要があるのは、見出しではない各要素の順序をランダム化することです。各見出しは最初のインデックスにとどまらなければならないが、2つの見出しの間の要素はランダム化されなければならない。付属の写真には、どのように見えるべきかの描写があります。
見出しと定期的な要素間の唯一の違いは、その値がこの#のH番号のように見える正規表現であるということである[0-9] +
だから、私がやったことだった: 私はを反復処理します各見出しのインデックスに注目してください。
次に、インデックス配列を繰り返し、複数のより小さな配列(各見出しに対して1つのグループ)に分割します。
次に、分割配列を含む配列を繰り返し、各配列をインデックス0からスプライスし(見出し要素を削除)、これらの値をシャッフルし、配列をシフトして先頭にヘッドライン要素を追加します。
最後に、splittedArrayOfArraysのすべての配列を必要な配列に連結します。これはcurrent.choicesです。
3回の繰り返しを実行するのはパフォーマンス上非常に賢明ではないようですが、配列から要素のグループのみをランダム化する方法はありますか?ここで
が、私はそれを動作させるために一緒にハッキングコードです:
var headlineIndexes = [];
var splittedArrayOfArrays = [];
for (var ii = 0; ii < current.choices.length; ii++) {
if (regex.test(current.choices[ii].value)) {
headlineIndexes.push(ii);
}
}
for (var ii = 0; ii < headlineIndexes.length; ii++) {
//if there is another headlineIndex, split Array until that index
if (headlineIndexes[ii + 1]) {
splittedArrayOfArrays[ii] = current.choices.slice(headlineIndexes[ii], headlineIndexes[ii + 1])
}
//if not, split until end of array
else {
splittedArrayOfArrays[ii] = current.choices.slice(headlineIndexes[ii]);
}
}
current.choices = [];
for (var ii = 0; ii < splittedArrayOfArrays.length; ii++) {
//remove first element and store in firstElem
var firstElem = splittedArrayOfArrays[ii].splice(0, 1);
//call shuffle with remaining elements, which shuffles the elements WITHOUT the headline
shuffle(splittedArrayOfArrays[ii]);
// re-add the headline as first elem of splittedArray
splittedArrayOfArrays[ii].unshift(firstElem[0]);
}
current.choices = splittedArrayOfArrays.reduce(function(prev, next) {
return prev.concat(next) ;
});
編集:私はsplittedArrayOfArraysを反復する理由はありませんでした実現し、すべてがforループを二から行われている可能性があります。私はこれが配列の中に持っている最大40桁の要素のために十分効率的だと思います。ここでは、最終的なコードです:3回の反復を実行
var headlineIndexes = [];
var splittedArrayOfArrays = [];
//save indexes at which we have headlines
for (var ii = 0; ii < current.choices.length; ii++) {
if (regex.test(current.choices[ii].value)) {
headlineIndexes.push(ii);
}
}
//split choices array into groups for each headline.
for (var ii = 0; ii < headlineIndexes.length; ii++) {
//if we have another headline, make new array with elements from current index to next index
if (headlineIndexes[ii + 1]) {
splittedArrayOfArrays[ii] = current.choices.slice(headlineIndexes[ii], headlineIndexes[ii + 1])
}
//else, new array from current index to end of choices array
else {
splittedArrayOfArrays[ii] = current.choices.slice(headlineIndexes[ii]);
}
//remove first element which is the headline, store in firstElem
var firstElem = splittedArrayOfArrays[ii].splice(0, 1);
//shuffle the choices of the group
shuffle(splittedArrayOfArrays[ii]);
//add the first element back to the first position of the group
splittedArrayOfArrays[ii].unshift(firstElem[0]);
}
//delete choices array
current.choices = [];
//concatenate group arrays into the choices array
current.choices = splittedArrayOfArrays.reduce(function(prev, next) {
return prev.concat(next) ;
});
ですが、元の配列をシャッフルしても配列内のグループは失われます。私はヘッドラインのインデックスを変更する必要はありませんし、グループ内の要素をシャッフルするだけです(したがって、配列を分割し、シャッフルして、それらをまとめる)。 –
配列の特定の範囲内で、2つの見出しの間にシャッフルするだけです。あなたはもちろん、事前にヘッドラインの位置を決定しなければならなかった。次に、インデックス0から最後まで配列をシャッフルする代わりに、見出しの直後のインデックスから次の見出しの前に、すべての範囲をシャッフルするまでインデックスから開始します。 – pfirpfel