.map() Карта 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 }
Я ничего не извлек из документации о новом протоколе итерации.
Мне известно wu.js, но я запускаю проект Babel и не хотите включать Traceur, который кажется, что он в настоящее время зависит от.
Я также немного не знаю, как извлечь как fitzgen/wu.js сделал это в мой собственный проект.
Мне понравилось бы ясное, краткое объяснение того, что мне здесь не хватает. Спасибо!
Документы для ES6-карты, FYI
Ответы
Ответ 1
Итак, .map
предлагает только одно значение, которое вам нужно...
Тем не менее, есть несколько способов решить эту проблему:
// instantiation
const myMap = new Map([
[ "A", 1 ],
[ "B", 2 ]
]);
// what 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
принимает любую итерабельность (в любое время вы используете [].slice.call( )
, а также Sets and Maps) и превращает его в массив...... Карты, когда принуждаются к массиву, превращаются в массив массивы, где el[0] === key && el[1] === value;
(в основном, в том же формате, что я предварительно заполнил свой пример Map with, выше).
Я использую деструктурирование массива в позиции аргумента лямбда, чтобы назначить эти точки массива значениям, прежде чем возвращать объект для каждого el.
Если вы используете Babel, в процессе производства вам понадобится браузер Babel polyfill (в который входят "core-js" и "регенератор" Facebook).
Я вполне уверен, что он содержит Array.from
.
Ответ 2
Вы должны просто использовать оператор распространения:
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]
Ответ 3
Просто используйте Array.from(iterable, [mapFn])
.
var myMap = new Map([["thing1", 1], ["thing2", 2], ["thing3", 3]]);
var newArr = Array.from(myMap.values(), value => value + 1);
Ответ 4
На самом деле вы можете иметь Map
с исходными ключами после преобразования в массив с помощью Array.from
. Это возможно, возвращая массив, где первый элемент - это key
, а второй - преобразованный value
.
const originalMap = new Map([
["thing1", 1], ["thing2", 2], ["thing3", 3]
]);
const arrayMap = Array.from(originalMap, ([key, value]) => {
return [key, value + 1]; // return an array
});
const alteredMap = new Map(arrayMap);
console.log(originalMap); // Map { 'thing1' => 1, 'thing2' => 2, 'thing3' => 3 }
console.log(alteredMap); // Map { 'thing1' => 2, 'thing2' => 3, 'thing3' => 4 }
Если вы не вернете этот ключ в качестве первого элемента массива, вы потеряете ключи Map
.
Ответ 5
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 }
Ответ 6
Используя 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 }
Ответ 7
Если вы не хотите заранее конвертировать всю карту в массив и/или разрушать массивы ключей, вы можете использовать эту глупую функцию:
/**
* 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
Ответ 8
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)
Зависит от вашего религиозного пыла, избегая редактирования прототипов, но, на мой взгляд, это позволяет мне сохранять его интуитивно понятным.
Ответ 9
Я предпочитаю расширять карту
export class UtilMap extends Map {
constructor(...args) { super(args); }
public map(supplier) {
const mapped = new UtilMap();
this.forEach(((value, key) => mapped.set(key, supplier(value, key)) ));
return mapped;
};
}
Ответ 10
Вы можете отобразить() массивы, но для Карт нет такой операции. Решение от доктора Аксель Раушмайер:
- Преобразуйте карту в массив пар [ключ, значение].
- Сопоставьте или отфильтруйте массив.
- Преобразуйте результат обратно в карту.
Пример:
let map0 = new Map([
[1, "a"],
[2, "b"],
[3, "c"]
]);
const map1 = new Map(
[...map0]
.map(([k, v]) => [k * 2, '_' + v])
);
привело к
{2 => '_a', 4 => '_b', 6 => '_c'}
Ответ 11
Вы можете использовать myMap.forEach и в каждом цикле использовать map.set для изменения значения.
myMap = new Map([
["a", 1],
["b", 2],
["c", 3]
]);
for (var [key, value] of myMap.entries()) {
console.log(key + ' = ' + value);
}
myMap.forEach((value, key, map) => {
map.set(key, value+1)
})
for (var [key, value] of myMap.entries()) {
console.log(key + ' = ' + value);
}
Ответ 12
Вы можете использовать эту функцию:
function mapMap(map, callback) {
return new Map(Array.from(map).map(([key, value]) => [key, callback(value, key, map)]));
}
использование:
var map1 = new Map([["A", 2], ["B", 3], ["C", 4]]);
var map2 = mapMap(map1, v => v * v);
console.log(map1, map2);
/*
Map { A → 2, B → 3, C → 4 }
Map { A → 4, B → 9, C → 16 }
*/