.карте() в JavaScript ES6 в карте?
Как бы вы это сделали? Инстинктивно я хочу сделать:
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
// wishful, ignorant thinking
var newMap = myMap.map((key, value) => value + 1); // Map { 'thing1' => 2, 'thing2' => 3, 'thing3' => 4 }
Я мало что почерпнул из документация по новому протоколу итерации.
Я в курсе Ву.js, а я Бабель проект и не хочу включать Трейсер, который похоже, что в настоящее время это зависит от.
Я также немного не знаю, как извлечь как fitzgen / wu.на JS сделал это в мой собственный проект.
хотел бы четкое, краткое объяснение того, что я здесь упускаю. Спасибо!
8 ответов:
так
.map
сам по себе предлагает только одно значение, о котором вы заботитесь... Тем не менее, есть несколько способов решения этой проблемы:// instantiation const myMap = new Map([ [ "A", 1 ], [ "B", 2 ] ]); // what's built into Map for you myMap.forEach( (val, key) => console.log(key, val) ); // "A 1", "B 2" // what Array can do for you Array.from( myMap ).map(([key, value]) => ({ key, value })); // [{key:"A", value: 1}, ... ] // less awesome iteration let entries = myMap.entries( ); for (let entry of entries) { console.log(entry); }
обратите внимание, я использую много нового материала в этом втором примере... ...
Array.from
принимает любой iterable (в любое время вы будете использовать[].slice.call( )
плюс наборы и карты) и превращает его в массив... ...Карты, когда их принудительно помещают в массив, превращаются в массив массивов, гдеel[0] === key && el[1] === value;
(в основном, в том же формате, что я предварительно заполнил мой пример карты, выше).Я используя деструктуризацию массива в позиции аргумента лямбды, чтобы назначить эти пятна массива значениям, прежде чем возвращать объект для каждого el.
если вы используете Babel, в производстве вам нужно будет использовать браузер Babel polyfill (который включает в себя "core-js" и "регенератор"Facebook).
Я совершенно уверен, что он содержитArray.from
.
вы должны просто использовать распространение оператор:
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]); var newArr = [...myMap].map(value => value[1] + 1); console.log(newArr); //[2, 3, 4] var newArr2 = [for(value of myMap) value = value[1] + 1]; console.log(newArr2); //[2, 3, 4]
просто использовать
Array.from(iterable, [mapFn])
.var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]); var newArr = Array.from(myMap.values(), value => value + 1);
const mapMap = (callback, map) => new Map(Array.from(map).map(callback)) var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]); var newMap = mapMap((pair) => [pair[0], pair[1] + 1], myMap); // Map { 'thing1' => 2, 'thing2' => 3, 'thing3' => 4 }
используя
Array.from
Я написал функцию Typescript, которая отображает значения:function mapKeys<T, V, U>(m: Map<T, V>, fn: (this: void, v: V) => U): Map<T, U> { function transformPair([k, v]: [T, V]): [T, U] { return [k, fn(v)] } return new Map(Array.from(m.entries(), transformPair)); } const m = new Map([[1, 2], [3, 4]]); console.log(mapKeys(m, i => i + 1)); // Map { 1 => 3, 3 => 5 }
Если вы не хотите заранее конвертировать всю карту в массив и / или разрушать массивы ключей-значений, вы можете использовать эту глупую функцию:
/** * Map over an ES6 Map. * * @param {Map} map * @param {Function} cb Callback. Receives two arguments: key, value. * @returns {Array} */ function mapMap(map, cb) { let out = new Array(map.size); let i = 0; map.forEach((val, key) => { out[i++] = cb(key, val); }); return out; } let map = new Map([ ["a", 1], ["b", 2], ["c", 3] ]); console.log( mapMap(map, (k, v) => `${k}-${v}`).join(', ') ); // a-1, b-2, c-3
Map.prototype.map = function(callback) { const output = new Map() this.forEach((element, key)=>{ output.set(key, callback(element, key)) }) return output } const myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]) // no longer wishful thinking const newMap = myMap.map((value, key) => value + 1) console.info(myMap, newMap)
зависит от вашего религиозного рвения в избегании редактирования прототипов, но, я считаю, что это позволяет мне держать его интуитивно понятным.