Подтвердить что ты не робот

.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

4b9b3361

Ответ 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 }
*/