Program Tip

반복기에서 map () 사용

programtip 2020. 11. 28. 10:20
반응형

반복기에서 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만으로도 충분합니다.


This simplest and most performant way is to use the second argument to Array.from to achieve this:

const map = new Map()
map.set('a', 1)
map.set('b', 2)

Array.from(map, ([key, value]) => `${key}:${value}`)
// ['a:1', 'b:2']

This approach works for any non-infinite iterable. And it avoids having to use a separate call to Array.from(map).map(...) which would iterate through the iterable twice and be worse for performance.


You could retrieve an iterator over the iterable, then return another iterator that calls the mapping callback function on each iterated element.

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

You could use itiriri that implements array-like methods for iterables:

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();

참고URL : https://stackoverflow.com/questions/43885365/using-map-on-an-iterator

반응형