reduce 메소드를 이용해서 문자열 길이 구하기
reducer (accumulate, currentValue, index)
리듀서 함수에서 인덱스를 세번째 인자로 넣을 수 있다는 문법적 사실에 기반하여 풀었습니다.- 반복문과
.length
를 사용하고 싶지 않았습니다.
function getStringLength(str) {
// 조건1. length 메소드 사용 금지.
// 조건2. 반복문 사용 금지
// 조건3. 파라미터로 들어오는 문자열이 빈 문자열일때는 0 리턴하기
if (str === '') {
return 0; // 조건 3 해결
} else {
let arr = str.split('');
return arr.reduce(function(acc, cv, idx){
return idx + 1;
})
}
}
여기에서 else문 안을 자세히 보면 다음과 같다.
- 우선적으로 배열의 메소드인 reduce를 활용하기 위해서
split() 메소드
를 활용하여 문자열을 배열로 변경하였다. - 리듀서 함수에서 우리가 원하는 것은 문자열 자체의 길이였다. 따라서 문자열로 생성한 배열의 마지막 인덱스 값에 1을 더한 것이 배열의 길이, 즉 문자열의 길이와 같다는 점을 활용하였다.
- ‘굳이 리듀스 함수를 썼어야 했을까?’ 라는 의구심이 들기는 했다.
‘Mushroom’이 들어간 피자만 골라줘 (Koans Advanced Solution)
- 피자 이름과 재료, 견과류 여부가 포함된 객체를 각각의 요소로 가지는 배열을 활용하여 문제를 푼다.
- 반복문을 사용하지 않고,
.map()
,.reduce()
를 사용해서 문제를 해결해라! - 원하는 결과물의 형태는 객체이고, 피자 재료들을 각각 카운트한 값을 값으로 가진다.
products 배열
// 피자 이름, 재료, 견과류 여부 가 담긴 각각의 객체를 배열의 요소로 가진다.
products = [
{ name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
{ name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
{ name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
{ name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
{ name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
];
문제를 잘라서 해결하기 1 - 결과를 담을 객체를 생성하고 재료만 담은 이중 배열 만들어주기.
// products 배열의 각각의 객체에서 'ingredients' 요소들만 뽑아준다.
products.map(function(el) {
return el.ingredients
})
map 메소드를 통해 나온 결과적인 배열은 아래와 같다.
[
["artichoke", "sundried tomatoes", "mushrooms"],
["roma", "sundried tomatoes", "goats cheese", "rosemary"],
["black beans", "jalapenos", "mushrooms"],
["blue cheese", "garlic", "walnuts"],
["spinach", "kalamata olives", "sesame seeds"]
]
문제를 잘라서 해결하기 2 - 이중 배열을 하나의 배열로 합치고, reduce로 객체화 하기
products.map(function(el) {
return el.ingredients}).flat().reduce(function(acc, cv){
// 1. acc 객체에 cv라는 키가 있는지? 값은 있는지? 조사
if (acc[cv] === undefined){
acc[cv] = 1 // acc 객체에 cv라는 키와 값이 속성으로 없다면 1을 주어라.
} else {
// 2. 만약에 존재한다면 해당 값에 1을 더해라.
acc[cv] = acc[cv] + 1
}
}, {}) // -> acc의 초기값은 결과값의 형태인 {}로 설정했다.
reduce 메소드를 통과한 배열은 아래와 같은 객체를 뱉는다. 피자를 만든는 것에 들어가는 재료의 카운트가 잘 이루어 진 것을 볼 수 있다.
{
artichoke:1,
sundried tomatoes:2,
mushrooms:2,
roma:1,
goats cheese:1,
rosemary:1,
black beans:1,
jalapenos:1,
blue cheese:1,
garlic:1,
walnuts:1,
spinach:1,
kalamata olives:1,
sesame seeds:1
}
여기에서 나는 flat()
메소드를 함께 사용했다. 해당 메소드의 활용은 다음과 같다.
let array = [[1], [2], [3], 4]
console.log(array.flat())
// -> [1, 2, 3, 4]