[javascript] 반복기에서 map () 사용

Map :이 있다고 가정 let m = new Map();하면 using m.values()은 맵 반복자 를 반환합니다.

하지만 사용할 수 없습니다 forEach()또는 map()그 반복자와 반복자 같은 ES6의 서비스 기능 이후 안티 패턴처럼 보인다에서 잠시 루프를 구현하는 방법에 대한 map().

map()반복자 에서 사용할 수있는 방법이 있습니까?



답변

이를 수행하는 가장 간단 하고 성능가장 낮은 방법은 다음과 같습니다.

Array.from(m).map(([key,value]) => /* whatever */)

더 나은

Array.from(m, ([key, value]) => /* whatever */))

Array.from반복 가능하거나 배열과 유사한 것을 취하여 배열로 변환합니다! Daniel이 주석에서 지적했듯이 변환에 매핑 함수를 추가하여 반복을 제거하고 이후에 중간 배열을 제거 할 수 있습니다.

사용 Array.from에서 성능 이동 O(1)O(n)코멘트에 밖으로 @hraban 점으로. 이후 mA는 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만으로도 충분합니다.


답변

이 가장 간단하고 가장 효과적인 방법은 두 번째 인수를 사용 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(..));


답변