Array.filter 자바스크립트 배열 필터링

원본: https://www.freecodecamp.org/news/filter-arrays-in-javascript/

대화형 앱을 만들다 보면 긴 목록을 필터링하는 버튼과 같이 동적인 기능을 넣어야 할 때가 있습니다. 또한 지정된 조건에 일치하는 항목만 리턴하도록 다수의 배열을 조작해야 할 수도 있습니다.

이 포스트에서는 자바스크립트 배열을 필터링하는 두 가지 방법을 알아보고 필터링된 요소로 이루어진 새 배열을 리턴하는 방법도 알아보겠습니다.

for 문 으로 배열 필터링

ES6가 도입되기 전에는 배열을 조작할 때 대부분의 개발자가 for 문을 사용했습니다.

하지만 이러한 구문은 코드를 길게 작성해야 하고 이해하기 어렵기 때문에 filter() 메소드와 같은 다양한 개별 메소드가 릴리즈되었습니다.

먼저 확실한 필터 과정을 이해하기 위해 for 문을 사용하여 필터링하는 방법을 알아보겠습니다.

name, age, occupation과 같은 사용자의 세부 정보를 가지는 객체 배열이 있다고 가정해보겠습니다. 이 배열에서 age가 특정 조건과 일치하는 사용자를 필터링해 보겠습니다.

const users = [
    { name: 'John', age: 25, occupation: 'gardener' },
    { name: 'Lenny', age: 51, occupation: 'programmer' },
    { name: 'Andrew', age: 43, occupation: 'teacher' },
    { name: 'Peter', age: 81, occupation: 'teacher' },
    { name: 'Anna', age: 47, occupation: 'programmer' },
    { name: 'Albert', age: 76, occupation: 'programmer' },
];

다음의 코드와 같이 객체 배열에서 age가 40 보다 크고 occupation이 programmer인 항목만 필터링할 수 있습니다.

let filteredUsers = [];

for (let i = 0; i < users.length; i++) {
    if (users[i].age > 40 && users[i].occupation === 'programmer') {
        filteredUsers = [...filteredUsers, users[i]];
    }
}

console.log(filteredUsers);

예제 코드를 개발자 도구console.log() 메소드를 통해 테스트해보면 다음과 같은 화면을 볼 수 있습니다.

for 문 필터링 예제

위의 코드는 의도대로 잘 작동합니다. 하지만 배열을 필터링하는 더 좋은 방법은 ES6의 filter() 메소드를 사용하는 것 입니다.

filter 메소드로 배열 필터링

이는 더 깔끔한 구문으로 배열을 필터링해주는 ES6 메소드입니다. 이 메소드는 원본 배열을 변경하지 않고 새 배열을 리턴합니다.

문법 구문은 다음과 같습니다:

myArray.filter(callbackFn);

콜백 함수에서 각각의 요소와 인덱스, 작업 중인 배열에 엑세스할 수 있습니다:

myArray.filter((element, index, array) => { /* ... */ });

이제 for 문을 사용한 예제와 동일하게 age와 occupation으로 배열을 필터링하는 코드를 살펴보겠습니다:

const filteredUsers = users.filter((user) => {
    return user.age > 40 && user.occupation === 'programmer';
});

console.log(filteredUsers);
filter 예제

위와 같이 작성하면 for 문과 출력 값이 정확히 동일하지만 코드가 매우 간결하다는 것을 알 수 있습니다.

또한 위의 코드와 동일한 기능을 하는 스크립트를 return 키워드를 제거하고 한 줄로 다시 작성할 수 있다는 점도 중요합니다.

const filteredUsers = users.filter(user => user.age > 40 && user.occupation === 'programmer');

console.log(filteredUsers);

filter() 메소드는 다른 메소드와 체인으로 사용할 수 있기 때문에 변수를 많이 만들지 않고도 여러 작업을 간단하게 수행할 수 있습니다.

예를 들면 필터링된 배열을 정렬하고 name만 리턴할 수도 있습니다:

const filteredUserNames = users.filter(user => user.age > 40 && user.occupation === 'programmer')
    .sort((a, b) => a.age - b.age)
    .map(user => user.name);

console.log(filteredUserNames);
filter chain 예제

filter 메소드로 객체 필터링

자바스크립트의 객체는 배열이나 문자열 처럼 루프를 돌 수 없습니다. 이는 filter() 메소드나 for 문 같은 루프 메소드를 직접 사용할 수 없음을 의미합니다. 그렇다면 어떻게 해야 할까요?

객체에서 루프를 돌려면 Object.keys(), Object.values(), Object.entries()와 같은 객체 정적 메소드를 사용하여 객체를 배열로 변환하고 filter() 메소드를 사용하여 배열을 필터링할 수 있습니다.

const userDetails = {
    firstName: "Jane",
    lastName: "Daniels",
    userName: "jane.daniels",
    email: "jane.daniels@example.com",
    comapny: "Example Inc.",
    address: "1234 Example Street",
    age: 25,
    hobby: "Singing",
};

const keysArray = Object.keys(userDetails);

console.log(keysArray);

위의 코드를 실행하면 다음과 같이 객체의 키 목록을 리턴합니다:

['firstName', 'lastName', 'userName', 'email', 'comapny', 'address', 'age', 'hobby']

여기에 filter() 메소드를 사용하면 배열에서 필터링된 요소의 새 배열을 얻을 수 있습니다.

const filteredKeys = keysArray.filter(key => key.length > 5);

console.log(filteredKeys);

위의 코드는 키 목록 중 키 문자열의 길이가 5 보다 큰 항목을 리턴합니다.

이 예제 보다는 더 실용적인 필터 작업을 알고 싶을 것 입니다.

예를 들어, 객체의 다양한 속성 중에서 필요한 속성에 해당하는 key/value 쌍을 필터링할 수 있습니다. 먼저 객체의 키 목록을 가져와 필터링하고 reduce() 메소드를 사용하여 원하는 key/value 쌍으로 이루어진 객체를 리턴하면 됩니다.

const userDetails = {
    firstName: "Jane",
    lastName: "Daniels",
    userName: "jane.daniels",
    email: "jane.daniels@example.com",
    comapny: "Example Inc.",
    address: "1234 Example Street",
    age: 25,
    hobby: "Singing",
};

const userNames = Object.keys(userDetails)
    .filter((key) => key.includes("Name"))
    .reduce((object, key) => {
        return Object.assign(object, {
            [key]: userDetails[key]
        });
    }, {});

console.log(userNames);
filter, reduce 예제

정리

이 포스트에서는 for 문 및 filter() 메소드를 사용하여 자바스크립트 배열을 필터링하는 방법을 알아보았습니다.

filter() 메소드는 배열을 필터링할 때 for 문 보다 더 나은 구문을 제공합니다.

관련 글