タイトルの通りなのだがやりたいことを説明
- JSONの配列がある
- その数より少ない要素数を指定して
- 配列の中からランダムに
- しかし重複なく
- 新しい配列を作成したい
なんだかいろいろと方法がありそうだが、できるだけ組み込み関数を利用して実装したい。
ランダムな要素抽出
const objs = [
{ title: "apple", price: 500 },
{ title: "orange", price: 200 },
{ title: "melon", price: 5000 },
{ title: "tako", price: 2500 },
{ title: "ika", price: 100 },
{ title: "mochi", price: 150 }
];
// console.log(objs);
const new_len = 3;
// 配列に使用すると 要素の数分の数値を出せる
// obj_keys = 0, 1, 2, 3, 4, 5 となる(以下)
var obj_keys = Object.keys(objs);
for (let i = 0; i < new_len; i++) {
// ランダムに obj_keys の範囲内で整数を選択して
// オブジェクトを表示する
var ran_key = obj_keys[Math.floor(Math.random() * obj_keys.length)];
console.log(objs[ran_key]);
}
最初の実装はこんな感じ。配列の要素数を Math.random() に書けることでインデックスに乱整数を入れて、要素を表示する。
実際には実行結果に重複が含まれる。
重複をチェックするには?
これが一番わかりやすい方法なんだがこれで良いのだろうか?ってコード。
const objs = [
{ title: "apple", price: 500 },
{ title: "orange", price: 200 },
{ title: "melon", price: 5000 },
{ title: "tako", price: 2500 },
{ title: "ika", price: 100 },
{ title: "mochi", price: 150 }
];
function intRandom(n_keys) {
return Math.floor(Math.random() * n_keys);
}
// 既出ランダム配列のindexを格納する配列
let selected_rand = [];
// すでに選択されたタイトルを格納する配列
let selected_titles = [];
const new_len = 3;
// 取り出したい配列の数だけループする
for (let i = 0; i < new_len; i++) {
// ランダム配列の取得ができるまでループする
while (true) {
var tmp = intRandom(objs.length);
if (!selected_rand.includes(tmp)) {
selected_rand.push(tmp);
selected_titles.push(objs[tmp].title);
break;
}
}
}
console.log(selected_objs);
できるだけ組み込み関数を利用するという部分で自信がないが。