配列が与えられた場合、それからn
サイズの重複しないランダムサンプルを抽出するにはどうすればよいm
ですか?
たとえば、配列が与えられた場合:
const arr = [1, 2, 3, 4, 5, 6, 7, 8];
呼び出しsample(arr, 3, 2)
例のリターンのためになり[[7, 8], [4, 5], [2, 3]]
、呼び出しsample(arr, 2, 4)
必ずしも戻ってくる[[1, 2, 3, 4], [5, 6, 7, 8]
と、呼び出しsample(arr, 5, 2)
エラーをスローしていました。
編集-おそらくこれは最初の質問では明確ではありませんでした:サンプルは連続した要素のリストでなければなりません。そのため、たとえば、sample(arr, 2, 4)
戻ることはできますが、返すことはでき[[1, 2, 3, 4], [5, 6, 7, 8]
ません[[2, 3, 1, 6], [5, 4, 7, 8]
。
最初に、戻り値の形式でリストを作成することから始めることができます。
[ 1, 2, 3, 4, 5, 6, 7, 8]
[<---->, <---->, <---->, <>, <>] // sample(array, 3, 2)
[<------------>, <------------>] // sample(array, 2, 4)
これらのフォーマット配列は、次の長さを使用して書き出すことができます。
[1, 2, 3, 4, 5, 6, 7, 8]
[ 2, 2, 2, 1, 1] // sample(array, 3, 2)
[ 4, 4] // sample(array, 2, 4)
次に、フォーマット配列をシャッフルして、ランダムなサンプルを選択します。
[1, 2, 3, 4, 5, 6, 7, 8]
[ 2, 1, 2, 2, 1] // sample(array, 3, 2)
[ 4, 4] // sample(array, 2, 4)
次に、フォーマット配列の各要素についてn
、入力配列から最初の要素を削除します。次に、フィラー(配列の長さに達するために配置される1つのサイズのチャンク)でない限り、それらを格納します。
[1, 2, 3, 4, 5, 6, 7, 8]
[[1,2], [4,5], [6,7]] // sample(array, 3, 2)
[[1,2,3,4], [5,6,7,8]] // sample(array, 2, 4)
最後に、結果のサンプルをシャッフルします。
[1, 2, 3, 4, 5, 6, 7, 8]
[[4,5], [1,2], [6,7]] // sample(array, 3, 2)
[[5,6,7,8], [1,2,3,4]] // sample(array, 2, 4)
const arr = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(sample(arr, 3, 2));
console.log(sample(arr, 2, 4));
console.log(sample(arr, 5, 2));
function randomInt(limit) {
return Math.floor(Math.random() * limit);
}
function shuffle(array) {
for (let limit = array.length; limit > 0; --limit)
array.push(...array.splice(randomInt(limit), 1));
}
function sample(array, sampleCount, sampleLength) {
let elementCount = sampleCount * sampleLength;
if (elementCount > array.length)
throw "invalid sampleCount/sampleLength arguments";
const filler = {valueOf: () => 1};
const fillerCount = array.length - elementCount;
const lengths = Array.from(
{length: sampleCount + fillerCount},
(_, i) => i < sampleCount ? sampleLength : filler
);
shuffle(lengths);
const samples = Array.from(array);
for (const length of lengths) {
const sample = samples.splice(0, length);
if (length === filler) continue;
samples.push(sample);
}
shuffle(samples);
return samples;
}
===
で重要であることに注意してくださいlength === filler
。を使用すると==
、filler
も等しくなり1
ます。これはsample(array, 5, 1)
、各サンプルの長さがであるような呼び出しと競合し1
ます。
const filler = {valueOf: () => 1};
console.log("1 == filler //=>", 1 == filler);
console.log("2 == filler //=>", 2 == filler);
console.log("filler == filler //=>", filler == filler);
console.log("1 === filler //=>", 1 === filler);
console.log("2 === filler //=>", 2 === filler);
console.log("filler === filler //=>", filler == filler);
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加