2017-02-13 3 views
1

Я играл с новой ES6 Map(), просто чтобы привыкнуть к ней, и теперь мы можем получить размер, мне пришло в голову, что можно эффективно брать случайные образцы карты, чтобы увидеть, что это выглядит как.Можно ли получить доступ к массиву, возвращаемому методом keys() объекта ES6 «Карта»?

Очевидно, что можно выполнить итерацию, сделать массив всех записей, а затем выбрать случайные образцы. Но это непривлекательно для больших карт.

В конце есть некоторый код, который достигает этого, используя новый доступный размер карты. Это немного более эффективно, чем копирование, но все же непривлекательно.

Но ключи метода Map() возвращают объект-итератор, метод next() которого мы обычно используем для итерации над экземпляром Map. И он также включает в себя массив всех записей. Это показано в следующем резюме выхода Chrome DevTools:

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-a-array –

+0

Извините, что не ясно, уточняется по вашему запросу. –

ответ

1

Если я правильно понимаю ваш вопрос, вы просто хотите получить случайный ключ от объекта карты.

Самого простой способ, что я могу думать, чтобы сделать это, чтобы привести объект итератора, возвращенный Map#keys в массив (с использованием либо разложенным оператор ... или Array.from), а затем просто получить доступ к случайному индексу

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));

+0

Спасибо, хорошо стоит услышать о распространении ... –

-3

Я согласен с изложенными выше замечаниями, что было бы полезно, если бы вы могли предоставить больше контекста. Если вы хотите перебирать ключи объекта, вам нужен массив. Для того, чтобы создать массив клавиш, которые можно использовать Object.keys() 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); 
1

Вы можете использовать спред элемент для преобразования Map в Array, Array.prototype.entries(), чтобы получить массив ключа, пар значений.

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);