Programing

JavaScript에서 집합을 매핑 / 축소 / 필터링하는 방법은 무엇입니까?

crosscheck 2020. 8. 31. 07:16
반응형

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의 변화를 기대 할 수 있습니다.

As for map, calling it alone could violate the Set constraint, so its presence here might be debatable.

Consider mapping with a function (a) => 42 - it will change the set's size to 1, and this might or might not be what you wanted.

If you're ok with violating that because e.g. you're going to fold anyway, you can apply the map part on every element just before passing them to reduce, thus accepting that the intermediate collection (which isn't a Set at this point) that's going to be reduced might have duplicated elements. This is essentially equivalent to converting to Array to do processing.


The cause of the lack of map/reduce/filter on Map/Set collections seem to be mainly conceptual concerns. Should each collection type in Javascript actually specify its own iterative methods only to allow this

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

instead of

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

An alternative were to specify map/reduce/filter as part of the iterable/iterator protocol, since entries/values/keys return Iterators. It is conceivable though that not every iterable is also "mappable". Another alternative were to specify a separate "collection protocol" for this very purpose.

However, I do not know the current discussion on this topic at ES.

참고URL : https://stackoverflow.com/questions/33234666/how-to-map-reduce-filter-a-set-in-javascript

반응형