[javascript] JavaScript에서 세트를 매핑 / 축소 / 필터링하는 방법?

JavaScript에서 map/ reduce/ filter/ etc를하는 방법이 Set있습니까? 아니면 내 자신을 작성해야합니까?

합리적인 Set.prototype확장 기능은 다음과 같습니다.

Set.prototype.map = function map(f) {
  var newSet = new Set();
  for (var v of this.values()) newSet.add(f(v));
  return newSet;
};

Set.prototype.reduce = function(f,initial) {
  var result = initial;
  for (var v of this) result = f(result, v);
  return result;
};

Set.prototype.filter = function filter(f) {
  var newSet = new Set();
  for (var v of this) if(f(v)) newSet.add(v);
  return newSet;
};

Set.prototype.every = function every(f) {
  for (var v of this) if (!f(v)) return false;
  return true;
};

Set.prototype.some = function some(f) {
  for (var v of this) if (f(v)) return true;
  return false;
};

조금만 설정합시다

let s = new Set([1,2,3,4]);

그리고 어리석은 작은 기능들

const times10 = x => x * 10;
const add = (x,y) => x + y;
const even = x => x % 2 === 0;

그리고 그들이 어떻게 작동하는지보십시오

s.map(times10);    //=> Set {10,20,30,40}
s.reduce(add, 0);  //=> 10
s.filter(even);    //=> Set {2,4}
s.every(even);     //=> false
s.some(even);      //=> true

멋지지 않습니까? 그래, 나도 그렇게 생각해 그것을 추악한 반복자 사용법과 비교하십시오.

// puke
let newSet = new Set();
for (let v in s) {
  newSet.add(times10(v));
}

// barf
let sum = 0;
for (let v in s) {
  sum = sum + v;
}

JavaScript 로 달성 map하고 reduce사용하는 더 좋은 방법이 Set있습니까?



답변

이를 수행하는 간단한 방법은 ES6 스프레드 연산자를 통해 배열로 변환하는 것입니다.

그런 다음 모든 어레이 기능을 사용할 수 있습니다.

const mySet = new Set([1,2,3,4]);
[...mySet].reduce()


답변

의견의 논의를 요약하면 :에 세트에 대한 기술적 이유가없는 동안 하지 가지고 reduce, 그것은 현재 제공되지 그리고 우리는 단지 그것을 ES7의 변화를 기대 할 수 있습니다.

에 관해서는 map그것을 단독으로 호출하면 Set제약 조건을 위반 할 수 있으므로 여기에서의 존재는 논란의 여지가 있습니다.

함수를 사용하여 매핑을 고려하십시오 (a) => 42-세트의 크기를 1로 변경하며, 이것이 원하는 것일 수도 아닐 수도 있습니다 .

어쨌든 배거야 예를 들어 있기 때문에, 당신이 적용 할 수있는 위반 나왔습니다 확인 당신이 만약 map단지로 전달하기 전에 모든 요소에 대한 부분을 reduce수용하여, 그 중간 (컬렉션 이 시점에서 설정되어 있지 않은 )의 그 축소 될 요소가 중복되었을 수 있습니다. 이것은 본질적으로 처리를 수행하기 위해 Array로 변환하는 것과 같습니다.


답변

map/ reduce/ filteron Map/ Set컬렉션 이없는 원인은 주로 개념적인 문제인 것 같습니다. 자바 스크립트의 각 컬렉션 유형은 실제로이를 허용하기 위해 자체 반복 메소드를 지정해야합니다

const mySet = new Set([1,2,3]);
const myMap = new Map([[1,1],[2,2],[3,3]]);

mySet.map(x => x + 1);
myMap.map(([k, x]) => [k, x + 1]);

대신에

new Set(Array.from(mySet.values(), x => x + 1));
new Map(Array.from(myMap.entries(), ([k, x]) => [k, x + 1]));

대안은 entries/ values/ keysreturn 이기 때문에 iterable / iterator 프로토콜의 일부로 map / reduce / filter를 지정하는 것 Iterator입니다. 모든 iterable이 “mappable”인 것은 아니지만 가능합니다. 또 다른 대안은이 목적을 위해 별도의 “수집 프로토콜”을 지정하는 것이 었습니다.

그러나 ES 에서이 주제에 대한 현재 토론을 모르겠습니다.


답변