Map :이 있다고 가정 let m = new Map();
하면 using m.values()
은 맵 반복자 를 반환합니다.
하지만 사용할 수 없습니다 forEach()
또는 map()
그 반복자와 반복자 같은 ES6의 서비스 기능 이후 안티 패턴처럼 보인다에서 잠시 루프를 구현하는 방법에 대한 map()
.
map()
반복자 에서 사용할 수있는 방법이 있습니까?
Map :이 있다고 가정 let m = new Map();
하면 using m.values()
은 맵 반복자 를 반환합니다.
하지만 사용할 수 없습니다 forEach()
또는 map()
그 반복자와 반복자 같은 ES6의 서비스 기능 이후 안티 패턴처럼 보인다에서 잠시 루프를 구현하는 방법에 대한 map()
.
map()
반복자 에서 사용할 수있는 방법이 있습니까?
Array.from(m.values()).map(...)
작동 하는 것처럼 매핑 하지만 이것이 최선의 방법은 아니라고 생각합니다.
Array#map
무엇입니까?
답변:
이를 수행하는 가장 간단 하고 성능 이 가장 낮은 방법은 다음과 같습니다.
Array.from(m).map(([key,value]) => /* whatever */)
더 나은
Array.from(m, ([key, value]) => /* whatever */))
Array.from
반복 가능하거나 배열과 유사한 것을 취하여 배열로 변환합니다! Daniel이 주석에서 지적했듯이 변환에 매핑 함수를 추가하여 반복을 제거하고 이후에 중간 배열을 제거 할 수 있습니다.
사용 Array.from
에서 성능 이동 O(1)
에 O(n)
코멘트에 밖으로 @hraban 점으로. 이후 m
A는 Map
, 그들이 무한 수 없습니다, 우리는 무한 순서에 대해 걱정할 필요가 없습니다. 대부분의 경우 이것으로 충분합니다.
지도를 반복하는 몇 가지 다른 방법이 있습니다.
forEach
m.forEach((value,key) => /* stuff */ )
for..of
var myMap = new Map();
myMap.set(0, 'zero');
myMap.set(1, 'one');
for (var [key, value] of myMap) {
console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one
이를 반복하기 위해 다른 반복기 함수를 정의 할 수 있습니다.
function* generator() {
for(let i = 0; i < 10; i++) {
console.log(i);
yield i;
}
}
function* mapIterator(iterator, mapping) {
while (true) {
let result = iterator.next();
if (result.done) {
break;
}
yield mapping(result.value);
}
}
let values = generator();
let mapped = mapIterator(values, (i) => {
let result = i*2;
console.log(`x2 = ${result}`);
return result;
});
console.log('The values will be generated right now.');
console.log(Array.from(mapped).join(','));
이제 질문 할 수 있습니다. Array.from
대신 사용하지 않는 이유는 무엇입니까? 이것은 전체 반복자를 통해 실행되므로 (임시) 배열에 저장하고 다시 반복 한 다음 매핑 을 수행합니다. 목록이 방대하거나 잠재적으로 무한한 경우 불필요한 메모리 사용량이 발생합니다.
물론 항목 목록이 상당히 적 으면 사용 Array.from
만으로도 충분합니다.
mapIterator()
iterator.return()
반환 값의 next가 한 번 이상 호출되지 않는 한 기본 반복기가 제대로 닫히 ( 호출) 보장되지 않습니다 . 참조 : repeater.js.org/docs/safety
이 가장 간단하고 가장 효과적인 방법은 두 번째 인수를 사용 Array.from
하여이를 달성하는 것입니다.
const map = new Map()
map.set('a', 1)
map.set('b', 2)
Array.from(map, ([key, value]) => `${key}:${value}`)
// ['a:1', 'b:2']
이 접근 방식은 무한 하지 않은 모든 반복 가능 항목에 적용됩니다. 그리고 Array.from(map).map(...)
iterable을 두 번 반복하고 성능이 더 나빠지 는 별도의 호출을 사용할 필요가 없습니다 .
이터 러블에 대한 이터레이터를 검색 한 다음 각 반복 요소에 대해 매핑 콜백 함수를 호출하는 또 다른 이터레이터를 반환 할 수 있습니다.
const map = (iterable, callback) => {
return {
[Symbol.iterator]() {
const iterator = iterable[Symbol.iterator]();
return {
next() {
const r = iterator.next();
if (r.done)
return r;
else {
return {
value: callback(r.value),
done: false,
};
}
}
}
}
}
};
// Arrays are iterable
console.log(...map([0, 1, 2, 3, 4], (num) => 2 * num)); // 0 2 4 6 8
iterables에 대해 배열과 유사한 메소드를 구현 하는 itiriri 를 사용할 수 있습니다 .
import { query } from 'itiriri';
let m = new Map();
// set map ...
query(m).filter([k, v] => k < 10).forEach([k, v] => console.log(v));
let arr = query(m.values()).map(v => v * 10).toArray();
https://www.npmjs.com/package/fluent-iterable을 살펴보십시오.
모든 이터 러블 (맵, 생성기 함수, 배열) 및 비동기 이터 러블과 함께 작동합니다.
const map = new Map();
...
console.log(fluent(map).filter(..).map(..));
lodash
map
Map을 지원하는 기능 과 같은 타사 라이브러리도 사용할 수 있습니다 .