programing

반복기에서 맵() 사용

telecom 2023. 11. 6. 21:40
반응형

반복기에서 맵() 사용

지도가 있다고 가정합니다.let m = new Map();,사용.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@hraban님이 댓글로 지적해주신 것처럼 에서 로 공연을 옮겨드립니다.부터mMap, 그들이 무한할 수는 없고, 우리는 무한한 서열에 대해 걱정할 필요가 없습니다.대부분의 경우 이 정도면 충분합니다.

지도를 우회하는 몇 가지 다른 방법이 있습니다.

사용.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* mapIter(iterable, callback) {
  for (let x of iterable) {
    yield callback(x);
  }
}

그리고 구체적인 결과를 원한다면 그냥 퍼짐 연산자를 사용하세요.....

[...mapIter([1, 2, 3], x => x**2)]

이를 루프오버하기 위해 다른 반복기 함수를 정의할 수 있습니다.

function* generator() {
    for (let i = 0; i < 10; i++) {
        console.log(i);
        yield i;
    }
}

function* mapIterator(iterator, mapping) {
    for (let i of iterator) {
        yield mapping(i);
    }
}

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충분해야 합니다.

이 가장 단순하고 가장 수행적인 방법은 두 번째 인수를 사용하여 이를 달성하는 것입니다.

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(...)두 번이나 반복할 수 있고 성능에 더 좋지 않을 겁니다

다양한 도우미 기능을 제공하는 제안이 있습니다.Iterator: https://github.com/tc39/proposal-iterator-helpers (rendered)

다음을 활용하여 지금 바로 사용할 수 있습니다.

import { from as iterFrom } from "core-js-pure/features/iterator";

// or if it's working for you (it should work according to the docs,
// but hasn't for me for some reason):
// import iterFrom from "core-js-pure/features/iterator/from";

let m = new Map();

m.set("13", 37);
m.set("42", 42);

const arr = iterFrom(m.values())
  .map((val) => val * 2)
  .toArray();

// prints "[74, 84]"
console.log(arr);

반복기를 통해 반복기를 검색한 다음 각 반복 요소에서 매핑 콜백 함수를 호출하는 다른 반복기를 반환할 수 있습니다.

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

https://www.npmjs.com/package/fluent-iterable 에서 만나보세요.

모든 반복 변수(Map, generator function, array) 및 비동기 변수와 함께 작동합니다.

const map = new Map();
...
console.log(fluent(map).filter(..).map(..));

배열과 유사한 메소드를 구현하는 itiri를 사용할 수 있습니다.

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

타이프스크립트 버전이 필요한 경우:

function* mapIter<T1, T2>(iterable: IterableIterator<T1>, callback: (value: T1) => T2) {
  for (let x of iterable) {
    yield callback(x);
  }
}

MartyO256(https://stackoverflow.com/a/53159921/7895659), 의 답변을 바탕으로 리팩토레이티드 타이프스크립트 접근 방식은 다음과 같습니다.

function mapIterator<TIn, TOut>(
  iterator: Iterator<TIn>,
  callback: (input: TIn) => TOut,
): Iterator<TOut> {
  return {
    next() {
      const result: IteratorResult<TIn> = iterator.next();

      if (result.done === true) {
        return result;
      } else {
        return {
          done: false,
          value: callback(result.value),
        };
      }
    },
  };
}

export function mapIterable<TIn, TOut>(
  iterable: Iterable<TIn>,
  callback: (input: TIn) => TOut,
): Iterable<TOut> {
  const iterator: Iterator<TIn> = iterable[Symbol.iterator]();
  const mappedIterator: Iterator<TOut> = mapIterator(iterator, callback);

  return {
    [Symbol.iterator]: () => mappedIterator,
  };
}

언급URL : https://stackoverflow.com/questions/43885365/using-map-on-an-iterator

반응형