배열이나 문자열에서 특정 요소를 찾고 싶을 때 indexOf 또는 findIndex를 사용한다.
비슷한 목적으로 사용하는 것 같지만, 근본적인 차이가 두 메서드 사이에는 존재한다. 추가로 find()도 살펴보자.
배열과 문자열에서 사용할 수 있는 메서드로, 특정 값이 해당 배열이나 문자열에 존재하면 처음 등장했을 때의 인덱스를 반환한다.
const animals = [ 'cat', 'dog', 'pig', 'lion', 'tiger', 'elephant'];
console.log(animals.indexOf('dog')) // 1
console.log(animals.indexOf('monkey')) // -1
const setence = 'The quick black cat jumps over the lazy tiger';
console.log(sentence.indexOf('cat')); // 16
console.log(sentence indexOf('fox')); // -1
cat이라는 단어가 존재하기 때문에 인덱스 값을 반환해야하는데, 이 때는 단어의 마지막 인덱스가 아니라 첫 번째 'c'의 인덱스 값을 반환한다.
배열에서: array.indexOf(찾고자 하는 요소[, 검색을 시작할 인덱스])
문자열에서: string.indexOf(찾고자 하는 요소[, 검색을 시작할 인덱스])
검색을 시작할 인덱스란?
문자열에서 찾기 시작하는 위치를 나타내는 인덱스 값이다. 배열의 길이보다 크거나 같은 경우에는 -1이 반환되고 배열이 검색되지 않는다. 기본 값은 0이고 문자열 전체를 대상으로 찾는다. 만약 인덱스 값이 음수라면 전체 문자열을 찾는다.
값이 음수라면 전체 문자열을 찾는다는 게 무슨 말이지...?
예를 들어 array = [ 'cat', 'dog', 'pig', 'lion', 'tiger', 'elephant']라는 배열이 있다고 하자.
array = [ 'cat', 'dog', 'pig', 'lion', 'tiger', 'elephant'];
array.indexOf('pig') // 2
array.indexOf('snake') // -1
array.indexOf('lion', 2) // 3
// 두 번째 인자는 시작점을 말하기 때문에 pig에서 부터 값을 검색하고,
// pig는 인덱스 값이 2인데 pig 바로 오른쪽에 lion이 위치하기 때문에 3이 반환된다.
// 시작점이 검색해야하는 값보다 큰 경우에는 -1을 반환한다.
array.indexOf('cat', 2) // -1
//array[2]는 pig인데 cat은 그 앞에 위치하기 때문에 검색이 되지 않는다.
// 그래서 -1을 반환한다.
이제 값이 음수일 때가 무슨 말인지 살펴보자.
array = [ 'cat', 'dog', 'pig', 'lion', 'tiger', 'elephant'];
array.indexOf('tiger', -1) // -1
// 검색을 시작할 인덱스 값에 음수가 오면 배열 가장 끝 값이 -1이 된다.
// 왼쪽으로 갈수록 점점 작은 값이 온다.
// [cat(-6), dog(-5), pig(-4), ..., elephant(-1)]
이 때, 시작점이 음수가 된 것이지 검색 방향이나 배열의 인덱스 값이 바뀌는 것은 아니다. 검색 방향은 왼쪽에서 오른쪽으로 진행하기 때문에 -1 값인 elephant 오른쪽에는 tiger가 존재하지 않는다. 따라서 검색이 되지 않으므로 -1이 반환되는 것이다.
근데 또 음수라고 늘 -1이 반환되는 것은 아니다.
만약 시작점이 -(찾고자 하는 요소)라면 무한대로 자신의 인덱스 값을 반환한다.
array = [ 'cat', 'dog', 'pig', 'lion', 'tiger', 'elephant'];
array.indexOf('tiger', -2) // 4
array.indexOf('tiger', -3) // 4
array.indexOf('tiger', -5) // 4
array.indexOf('tiger', -7) // 4
array.indexOf('tiger', -9) // 4
indexOf 메서드는 검색할 때 값과 타입이 같은 일치 비교를 통해 요소를 찾아낸다. 또한 아무리 아무리 찾고자 하는 요소가 배열 또는 문자열에 여러번 등장해도 첫 번째로 검색된 요소의 인덱스만을 반환한다.
findIndex 메서드는 ES6에서 특별히 배열을 위해 도입된 고차 함수이다. 제공된 함수를 만족하는 배열의 첫 번째 요소를 검색하고 해당 인덱스를 반환한다. 보통 배열 안에 있는 값이 객체이거나, 특정 조건을 활용해 인덱스를 찾아야할 때 사용한다. 이 메서드도 만족하는 요소가 없으면 -1을 반환한다.
array.findIndex(callbackFn(element[, index[, array]])[, thisArg])
// array.findIndex(callback(배열에서 처리중인 현재 요소([, 처리 중인 현재 요소의 인덱스[, findIndex()가 호출된 배열]])[, thisArg])
callback함수는 배열의 각 요소마다 실행할 함수이다. 일치하는 요소가 발견되었음을 나타내는 참인 값을 반환하고 그렇지 않으면 거짓인 값을 반환한다.
thisArg는 콜백함수를 실행할 때 사용할 선택적 객체, 즉 this로 사용할 값이다. 생략할 수도 있는데 그 때 findIndex() 함수는 undefined를 사용한다.
const lotto = [13, 14, 16, 18, 21, 34, 33];
const index = lotto.findIndex(num => num === 21);
console.log(index); // 4
const age = [3, 7, 15, 35, 39, 22, 7];
const index = age.findIndex(
(num, index) => num === 7 && index > 3
);
console.log(index); // 6
const friends = [
{name: 'Tom', hometown: 'Seoul'},
{name: 'Jane', hometown: 'Taiwan'},
{name: 'Lucy', hometown: 'Canada'},
{name: 'Peter', hometown: 'the Philippines'},
]
const index = friends.findIndex(friend => friend.hometown === 'Canada');
console.log(index) // 2
find 메서드는 제공된 배열에서 제공된 테스트 함수를 만족하는 첫 번째 요소를 반환한다. 만족하는 값이 없으면 undefined가 반환된다. 반환하는 값이 인덱스가 아니라 해당 원소나 객체이다.
array.find(callbackFn(element[, index[, array]])[, thisArg])
// array.findIndex(callbackFn(배열에서 처리중인 현재 요소([, 처리 중인 현재 요소의 인덱스[, find()가 호출된 배열]])[, thisArg])
const snacks = [
{name: '새우깡', price: 3000},
{name: '포카칩', price: 1900},
{name: '양파링', price: 3200},
{name: '오잉', price: 2500},
{name: '썬칩', price: 2300}
];
const found = snacks.find(({ name }) => name === '포카칩');
console.log(found); // { name: '포카칩', price: 1900 }
참고: https://developer.mozilla.org
참고: https://medium.com/front-end-weekly/the-difference-between-indexof-and-findindex-in-javascript-a2035639dce5
참고: https://velog.io/@zwonlala/배열-내장함수-indexOf-findIndex-find
참고: https://bomango.tistory.com/46
참고: https://5takoo.tistory.com/222
세 메서드의 성능 차이도 찾아보면 좋겠네요ㅎㅎㅎ