reduce 메소드를 이용해서 문자열 길이 구하기



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문 안을 자세히 보면 다음과 같다.

  1. 우선적으로 배열의 메소드인 reduce를 활용하기 위해서 split() 메소드를 활용하여 문자열을 배열로 변경하였다.
  2. 리듀서 함수에서 우리가 원하는 것은 문자열 자체의 길이였다. 따라서 문자열로 생성한 배열의 마지막 인덱스 값에 1을 더한 것이 배열의 길이, 즉 문자열의 길이와 같다는 점을 활용하였다.
  3. ‘굳이 리듀스 함수를 썼어야 했을까?’ 라는 의구심이 들기는 했다.




‘Mushroom’이 들어간 피자만 골라줘 (Koans Advanced Solution)


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]