const log = console.log;
const products = [
{name: '반팔티', price: 15000},
{name: '긴팔티', price: 20000},
{name: '핸드폰케이스', price: 15000},
{name: '후드티', price: 30000},
{name: '바지', price: 25000}
];
map
[명령형]
let names = [];
for (const p of products) {
names.push(p.name);
}
log(names);
let prices = [];
for (const p of products) {
prices.push(p.price);
}
log(prices);
[map 함수의 구현]
const map = (f, iter) => {
let res = [];
for (const a of iter) {
res.push(f(a)); // 함수를 추상화
}
return res;
}
log(map(p => p.name, products));
log(map(p => p.price, products));
이터러블 프로토콜을 따른 map의 다형성
- 이터러블 프로토콜만 따르면 자체 메서드가 없어도 map을 쉽게 사용 가능
[prototype에 map 이 없는 iterable에 map 적용]
log([1, 2, 3].map(a => a + 1));
// log(document.querySelectorAll('*').map(a => ...))
// NodeList는 map 이 없다고 에러가 난다
log(map(el => el.nodeName, document.querySelectorAll('*')));
// 이터러블 프로토콜을 따르고 있어서 사용자 정의 map 사용 가능
// const it = document.querySelectorAll('*')[Symbol.iterator]();
// log(it.next());
// log(it.next());
// log(it.next());
// log(it.next());
// log(it.next());
[그외 iterable 프로토콜 따르는 것들도 사용자 정의 map 적용 가능]
function* gen() {
yield 2;
if (false) yield 3;
yield 4;
}
log(map(a => a * a, gen()));
let m = new Map();
m.set('a', 10);
m.set('b', 20);
log(new Map(map(([k, a]) => [k, a * 2], m)));
console.clear();
filter
[명령형]
let under20000 = [];
for (const p of products) {
if (p.price < 20000) under20000.push(p);
}
log(...under20000);
let over20000 = [];
for (const p of products) {
if (p.price >= 20000) over20000.push(p);
}
log(...over20000);
[filter 함수 구현]
const filter = (f, iter) => {
let res = [];
for (const a of iter) {
if (f(a)) res.push(a);
}
return res;
};
log(...filter(p => p.price < 20000, products));
log(...filter(p => p.price >= 20000, products));
// 이터러블 프로토콜만 이용하면 다 이용가능
log(filter(n => n % 2, [1, 2, 3, 4]));
log(filter(n => n % 2, function* () {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}()));
console.clear();