TIL

2024.03.29 TIL #indexOf_vs_findIndex #문자열나누기_프로그래머스

inz1234 2024. 3. 30. 18:33

안다고 생각했는데도 자꾸 헷갈려서 정리해보려 한다.  

 

indexOf

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];

console.log(beasts.indexOf('bison'));
// Expected output: 1

// Start from index 2
console.log(beasts.indexOf('bison', 2));
// Expected output: 4

console.log(beasts.indexOf('giraffe'));
// Expected output: -1

보는 것과 같이 indexOf는 배열.indexOf(해당요소) 가 들어간다.

 

findIndex

function isPrime(element) {
  if (element % 2 === 0 || element < 2) {
    return false;
  }
  for (let factor = 3; factor <= Math.sqrt(element); factor += 2) {
    if (element % factor === 0) {
      return false;
    }
  }
  return true;
}

console.log([4, 6, 8, 9, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 9, 12].findIndex(isPrime)); // 2 (array[2] is 7)

findIndex는 매개인자에 콜백함수가 들어가고, 그 콜백함수의 true 값을 반환하는 요소의 순서를 찾는 메서드다.


다만, indexOf 와 findIndex 모두 조건을 반환하는 첫번째 요소만 찾아준다는 특징이 있다.

그것을 간과하고 썼다가 고생한 사례가 바로 이런 사례다.

프로그래머스의 문자열 나누기 라는 문제다.

 

<틀린 답안>

let s = "ccaabbab";
function solution(s) {
let sArr = s.split("");
let sCount = 0;
let dCount = 0;
let tCount = 0;

sArr.forEach((s) => {
  if (sArr.indexOf(s) === 0) {
    sCount++
  } else {
    if (s !== sArr[sArr.indexOf(s) - 1]) {
      dCount++;
    } else {
      sCount++;
    }
  }
  if (sCount === dCount) {
    tCount++;
    sCount = 0;
    dCount = 0;
    console.log("현재 순서", sArr.indexOf(s));
    sArr = sArr.slice(sArr.indexOf(s) + 1);
  }
  if (sCount !== dCount && sArr.length === 1) {
    tCount++;
  }
});
return tCount;
}

sArr = sArr.slice(sArr.indexOf(s) + 1) 

바로 이 부분에서, 나는 sArr[3]번째 a의 순서 기준으로 sArr를 [b,b,a,a]로 재설정하고 싶었다. 
그런데 indexOf는 첫 번째 요소만을 반환하기 때문에 나의 의도인 sArr[3]번째 a가 아닌 

sArr[2]번째 a를 기준으로 sArr를 재설정하고 있었다.

 

참... 별거 아닌 거 같다고 생각했는데 시간을 너무 많이 소비해버렸다.

 

수정된 나의 답안은

 

<정답>

function solution(s) {
let sArr = s.split("");
let sCount = 0;
let dCount = 0;
let tCount = 0;
let idx = 0;

sArr.forEach((s) => {
  if (sArr.indexOf(s) === 0) {
    sCount++;
  } else {
    if (s !== sArr[sArr.indexOf(s) - 1]) {
      dCount++;
    } else {
      sCount++;
    }
  }
  if (sCount === dCount) {
    tCount++;
    sCount = 0;
    dCount = 0;
    sArr = sArr.slice(idx + 1);
    idx = 0;
  }
  if (sCount !== dCount && idx === sArr.length - 1) {
    tCount++;
  }
  idx === 0 && sCount === 0 ? (idx = 0) : idx++;
});
return tCount;
}

이렇게 되었다.

 


오늘의 교훈

안다고 깝치지 말자..