2017-02-13 5 views
1

私は新しいES6マップ()に慣れてきました。サイズを取得できるようになりました。マップの無作為なサンプルを効率的に取ることができました。ように見えた。ES6のMapオブジェクトのkeys()メソッドから返された配列にアクセスできますか?

明らかに、すべての項目の配列を反復し、ランダムサンプルを選択することは可能です。しかし、これは大きな地図では魅力的ではありません。

最後に、マップの新しく利用可能なサイズを利用してこれを実現するコードがあります。コピーよりもやや効率的ですが、まだ魅力的ではありません。

しかし、Mapメソッドkeys()はイテレータオブジェクトを返します。イテレータオブジェクトはmapインスタンスに対して通常反復処理を行うnext()メソッドを返します。また、すべてのエントリの配列も含まれています。これは、クロムデベロッパーツールの出力の次の要約に示されている:

coinNames.keys() 
MapIterator 
"keys" 
.... 
[[Entries]] 
: 
Array[7] 
0 
: 
30 
1 
: 
12 

... (entries omitted) 

length 
: 
7 

私は、配列のインデックスでエントリを見つけるように、この配列にアクセスする方法を見つけることができませんでした。

以下のコード(get_random_integer()とreport()...)が機能しています。

関数play()は、ボタンを押すと呼び出され、ランダムな名前が記録されます。

しかし、反復しないで、配列内の指定された位置にエントリを取得するといいでしょう。

アイデア?

function CoinName(name, slang, plural) { 
    this.name = name; 
    this.plural = plural; 
} 
const coinNames = new Map(); 

window.onload = init; 
function init() { 
    report ('OK'); 
    var button = document.getElementById('buttonA'); 
    button.addEventListener('click', play); 

    coinNames.set(30, new CoinName('half crown')); 
    coinNames.set(12, new CoinName('shilling', 'bob')); 
    coinNames.set(3, new CoinName('threepenny bit')); 
    coinNames.set(6, new CoinName('sixpence', 'tanner')); 
    coinNames.set(1, new CoinName('penny', '', 'pence')); 
    coinNames.set(1/4, new CoinName('farthing')); 
    coinNames.set(1/2, new CoinName('halfpenny', 'hapeny', 
          'halfpence')); 
} 

function getRandomKey() { 
    let requiredIndex = get_random_integer(0, coinNames.size); 

    let keys = coinNames.keys(); 
    let found = undefined; 
    let goon = true; 
    let i = 0; 
    while(goon) { 
     goon = keys.next().value; 
     //report(goon); 
     if(goon && i===requiredIndex) { 
      found = goon; 
      goon = false; 
     } 
     i += 1;  
    } 
    return found; 
} 

function play() { 
    let key = getRandomKey(); 
    let entry = coinNames.get(key); 
    report(entry.name); 
} 
+2

私は、あなたが「それを得ることができない」によって何を意味するかわかりません。 http:// stackoverflow。com/questions/4550505/get-random-value-from-array –

+0

ご不明な点がございましたら、ご遠慮なくご連絡ください。 –

答えて

1

質問が正しく分かったら、Mapオブジェクトからランダムなキーを取得したいだけです。

これを実現するために私は考えることができる最も簡単な方法は、(スプレッドオペレータ...、またはArray.fromのいずれかを使用して)配列にMap#keysによって返されたイテレータオブジェクトをキャストすることで、単にランダムインデックスに

const map = [['a','1'],['b','2'],['c','3']].reduce((m, e) => m.set(...e), new Map()); 
 
const getRandKey = map => [...map.keys()][Math.floor(Math.random() * 1000) % map.size]; 
 
let i = 10; while(i-- > 0) console.log(getRandKey(map));
にアクセスあなたは Mapから ArrayArray.prototype.entries()は、キーと値のペアの配列を取得するために変換するために、スプレッド要素を使用することができます

+0

ありがとう、広がりを聞く価値がある... –

-3

私はあなたがより多くのコンテキストを提供することができれば、それは参考になることを上記のコメントに同意します。つまり、オブジェクトのキーを繰り返し処理する場合は、配列が必要です。キーの配列を作成するには、https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

const america = { 
    California: "Sacramento", 
    NewYork: "New York", 
    Texas: "Austin" 
} 

const capitals = (america) => { 
    let result = [] 
    for (var key in america) { 
    result.push(america[key]) 
    } 
    return result; 
} 
console.log(capitals(america)) 

const states = Object.keys(america) 
console.log(states); 
0

[[Entries]]は、イテレータのアクセスできないinternal slotである()Object.keysを使用することができます。実装の詳細ですが、language standardで指定されていません。あなたはそれに乗ることはできません。

1

const map = new Map; 
 

 
map.set(2, {abc:123}); 
 
map.set(7, {def:456}); 
 
map.set(1, {ghi:789}); 
 

 
let entries = [...map]; 
 
let len = entries.length; 
 
let key = Math.floor(Math.random() * len); 
 
let [prop, value] = entries[key]; 
 

 
console.log(prop, value);

関連する問題