JavaScript 배열 메소드(2)

seul_velog·2021년 12월 8일
0

JavaScript

목록 보기
14/25
post-thumbnail

📌 여러가지 문제를 통해서 다양한 배열의 메소드 사용 방법을 익혀보자! 🤔

1. Array.prototype.join() & toString()

Q1. 주어진 배열을 스트링으로 변환하기

const fruits = ['apple', 'banana', 'orange'];


// ▼ answer
const result = fruits.join();

console.log(result);  // "apple,banana,orange"

📌 join(separator?: string): string;
📌 toString(): string;
🔒 join() 메소드는 원본 배열를 변경하지 않는다.

✍️
처음에는 console.log(fruits.toString()); 으로 작성해서, 위와 같은 결과가 나오는 걸 확인 할 수 있었다. 결과는 비슷해도 방식이 다른데, 그렇다면 두 개의 차이점은 뭘까?

(1) join()
: 배열의 모든 요소를 연결해 하나의 문자열로 만든다. 파라미터로 구분 기호(separator)를 사용하면, 문자열 형태로 나열할 때 구분 기준이되는 구분자로 명시되는데 이를 생략하면 , 로 자동 적용된다.
+) 파라미터를 ('') 로 하면 비어있는 문자열을 전달하여 배열의 각 값들을 구분자 없이 연결한 문자열이 리턴된다. (예제참고)

(2) toString()
: 배열뿐만 아니라 다른 유형의 객체에도 사용할 수 있으며 객체의 값을 문자열로 변환하는 데 사용된다. 값은 쉼표로 구분된다.
( toString() 은 오브젝트에서 어떻게 오버라이딩해서 구현했냐에 따라서, 즉 오브젝트마다 똑같은 결과가 나올 수도 있고 아닐 수도 있다고 한다. )

// ex) join()
const result1 = fruits.join(';');  // "apple;banana;orange"
const result2 = fruits.join('-');  // "apple-banana-orange"
const result3 = fruits.join('');  // "applebananaorange"
const result4 = fruits.join(' or ');  // "apple or banana or orange"

// ex) toSting()
const result = fruits.toString(';');  // "apple,banana,orange"


2. String.prototype.split()

Q2. 주어진 문자열을 배열로 변환하기

const fruits = '🍎, 🥝, 🍌, 🍒';


// ▼ answer
const result = fruits.split(',');

console.log(result);  // ["🍎", "🥝", " 🍌", " 🍒"]

📌 split(separator: string | RegExp, limit?: number): string[];
🔒 split() 메소드는 원본 배열를 변경하지 않는다.

✍️
split() 는 총 두가지의 parameter 를 받는다.
(1) separator (구분자)
: 필수적으로 전달해야하는 구분자를 전달하지 않으면 아래 예제처럼 문자열 전체가 한곳에 들어있는 것이 확인된다.

(2) limit
: 우리가 리턴받을 배열의 사이즈를 지정한다. 만약 첫번째 두개의 배열을 전달 받고 싶다면 아래 예제와 같이 2를 적으면 된다.

// ex1.) separator (필수)
const result1 = fruits.split();
console.log(result1);  // ["🍎, 🥝, 🍌, 🍒"]


// ex2.) limit 설정(옵션)
const result2 = fruits.split(',',2);
console.log(result2);  // ["🍎", "🥝"]


3. Array.prototype.reverse() ❗️

Q3. 주어진 배열의 순서를 거꾸로 만들기

const array = [1, 2, 3, 4, 5];


// ▼ answer
const result = array.reverse();

console.log(result);  // [5, 4, 3, 2, 1]
console.log(array);  // [5, 4, 3, 2, 1]

📌 reverse(): T[];
❗️ reverse() 메소드는 원본 배열이 변경된다.

✍️
reverse() 는 배열안에 들어있는 아이템의 순서를 거꾸로 만들어 준다. 함수를 호출한 array 배열 자체도 순서가 바뀐다.



4. Array.prototype.slice() & splice() ❗️

Q4. 주어진 배열에서 첫번째, 두번째 요소를 제외하고 나머지 세개만 들어있는 새로운 배열을 만들기

const array = [1, 2, 3, 4, 5];


// ▼ answer
const result = array.slice(2, 5);

console.log(result);  // [3, 4, 5]
console.log(array);  // [1, 2, 3, 4, 5]

📌 slice(start?: number, end?: number): T[];
📌 splice(start: number, deleteCount: number, ...items: T[]): T[];
🔒 slice() 메소드는 원본 배열를 변경하지 않는다.
❗️ splice() 메소드는 원본 배열이 변경된다.

✍️
slice()와 splice() 두 개의 방법으로 같은 결과를 출력할 수 있지만, 정답은 slice()만 해당된다. 그렇다면 두 개의 차이점은 무엇인지 알아보자.

(1) slice()
: 배열에서 원하는 부분만 리턴해서 받아오고 싶을 때 쓴다. 원본 배열은 변경되지 않는다.
첫번째 매개변수 start에 해당하는 인덱스를 갖는 요소부터 매개변수 end에 해당하는 인덱스를 가진 요소 전까지 복사된다.

(2) splice()
: 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경한다. (우리는 배열 자체를 변경하지 않고 새로운 배열을 만들어야 하므로 정답이 될 수 없다.)

//ex) splice()
const array = [1, 2, 3, 4, 5];
const result = array.splice(1,2,6);

console.log(result);  // [2, 3]
console.log(array);  // [1, 6, 4, 5]



5. Array.prototype.find()

Q5. 점수가 90점인 학생을 찾기

  class Student {
    constructor(name, age, enrolled, score) {
      this.name = name;
      this.age = age;
      this.enrolled = enrolled;
      this.score = score;
    }
  }

  const students = [
    new Student('A', 29, true, 45),
    new Student('B', 28, false, 80),
    new Student('C', 30, true, 90),
    new Student('D', 40, false, 66),
    new Student('E', 18, true, 88),
  ];


// ▼ answer
const result = students.find((value) => value.score === 90);

/* ▼ arrow function으로 정의하기 전 코드
 * const result = students.find(function(value){
 *   return value.score === 90;
 * });
 */

console.log(result);
// Student {name: 'C', age: 30, enrolled: true, score: 90}

📌 find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
🔒 find() 메서드는 원본 배열를 변경하지 않는다.

✍️
find() 는 주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환하고 없다면 undefined를 반환한다.

문제에서 전달한 콜백함수는 배열에 있는 모든 요소들 마다 순차적으로 하나씩 호출이 되는데, 학생의 점수가 90점이면 true , 아니라면 false 를 리턴 한다. 그리고 find 는 처음으로 true 가 나오면 해당하는 그 배열의 요소를 리턴해주는 API이다 (원하는 것을 찾을 때 유용하게 사용)


find() 예제를 하나 작성해보자.

// ex)
const array1 = [5, 10, 15, 20, 30];


// ▼ answer
const found = array1.find((item) => item > 15);

/* ▼ arrow function으로 정의하기 전 코드
 * const found = array1.find(function(item){
 *  return item > 15;
 * });
 */

console.log(found);  // 20;

✍️
15보다 높은 숫자가 처음으로 나온 요소를 리턴한다.



6. Array.prototype.filter()

Q6. 수업에 등록된 학생들의 배열을 만들기

class Student {
  constructor(name, age, enrolled, score) {
    this.name = name;
    this.age = age;
    this.enrolled = enrolled;
    this.score = score;
  }
}

const students = [
  new Student('A', 29, true, 45),
  new Student('B', 28, false, 80),
  new Student('C', 30, true, 90),
  new Student('D', 40, false, 66),
  new Student('E', 18, true, 88),
];


// ▼ answer
const result = students.filter((element) => element.enrolled);

console.log(result); 

📌 filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
🔒 filter() 메소드는 원본 배열를 변경하지 않는다.

✍️
filter() 는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.



7. Array.prototype.map()

Q7. 학생의 점수(score)만 포함하는 배열 만들기

class Student {
  constructor(name, age, enrolled, score) {
    this.name = name;
    this.age = age;
    this.enrolled = enrolled;
    this.score = score;
  }
}

const students = [
  new Student('A', 29, true, 45),
  new Student('B', 28, false, 80),
  new Student('C', 30, true, 90),
  new Student('D', 40, false, 66),
  new Student('E', 18, true, 88),
];


// ▼ answer
const result = students.map((student) => student.score);

console.log(result);  // [45, 80, 90, 66, 88]

📌 map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
🔒 map() 메소드는 원본 배열를 변경하지 않는다.

✍️
map() 은 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다. 배열안에 있는 각각의 요소에 우리가 전달해준 콜백함수를 호출하면서, 콜백함수에서 가공되어진 다른방식의 데이터를 만들고 싶을때 유용하게 쓸 수 있다.

📌 Point !
콜백함수로 전달되어지는 인자는 최대한 이해하기 쉽도록 쓰는것이 중요하다.
위의 5번, 6번 문제에서 콜백함수에서 전달되어지는 인자를 value , item, element 와 같이 이름지어서 전달했는데, 협업을 하거나 긴 코드를 작성할 때 이러한 이름이 많아지면 가독성이 떨어질 수 있다. 때문에 'student'와 같이 의미있는 이름을 짓는 것이 중요하다! 😃



8. Array.prototype.some() & every()

Q8. 50점 미만의 학생이 있는지 확인하기

class Student {
  constructor(name, age, enrolled, score) {
    this.name = name;
    this.age = age;
    this.enrolled = enrolled;
    this.score = score;
  }
}

const students = [
  new Student('A', 29, true, 45), 
  new Student('B', 28, false, 80),
  new Student('C', 30, true, 90),
  new Student('D', 40, false, 66),
  new Student('E', 18, true, 88),
];


// ▼ answer
const result1 = students.some((student) => student.score < 50);
console.log(result1);  // true

const result2 = !students.every((student) => student.score >= 50);
console.log(result2);  // true (가독성이 좋지 않다.)

📌 some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
📌 every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
🔒 some() 메소드는 원본 배열를 변경하지 않는다.
🔒 every() 메소드는 원본 배열를 변경하지 않는다.

✍️
(1) some()
: 배열 안의 어떤 요소라도 주어진 판별 함수를 통과하는지 확인한다.
콜백함수는 이 배열에 있는 요소 하나하나씩 수행되는데, 배열에서 하나라도 이 조건에 만족되는 사람이 있다면 트루가 리턴되는 것이다.

(2) every()
: 배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 확인한다.
모든 배열의 조건이 만족 되어야 할 경우에만 every 를 쓰는 것이 가독성에 좋다.



9. Array.prototype.reduce()

Q9. 학생들의 평균 점수를 계산하기

class Student {
  constructor(name, age, enrolled, score) {
    this.name = name;
    this.age = age;
    this.enrolled = enrolled;
    this.score = score;
  }
}

const students = [
  new Student('A', 29, true, 45),
  new Student('B', 28, false, 80),
  new Student('C', 30, true, 90),
  new Student('D', 40, false, 66),
  new Student('E', 18, true, 88),
];


// ▼ answer
const result = students.reduce((prev, curr) => prev + curr.score, 0);

console.log(result / students.length);  // 73.8

📌 reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
🔒 reduce() 메소드는 원본 배열를 변경하지 않는다.

✍️
reduce() 는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환한다.
reducecallbackinitialValue 를 전달하고, 원하는 시작점부터 모든 배열을 돌면서 어떤 값을 누적할 때 쓴다.
마지막 행에서 결과를 출력할 때 학생 길이 만큼 나눠주면 누적된 값의 평균값을 구할 수 있다.



10. map() & filter() & sort() & join()

Q10. 조건에 맞는 점수를 포함하는 문자열 만들기

class Student {
  constructor(name, age, enrolled, score) {
    this.name = name;
    this.age = age;
    this.enrolled = enrolled;
    this.score = score;
  }
}

const students = [
  new Student('A', 29, true, 45),
  new Student('B', 28, false, 80),
  new Student('C', 30, true, 90),
  new Student('D', 40, false, 66),
  new Student('E', 18, true, 88),
];


// ▼ answer
const result = students
.map(student => student.score)  // 스코어만 담긴 배열을 만들고,  
.filter((score) => score >= 50)  // (조건) 점수가 50 이상인 아이들만,
.sort((a, b) => a - b)  // 작은 순서부터 차례대로, 
.join(); // 문자열로 바꿔서 출력한다.

console.log(result);  // 66,80,88,90 

✍️
(1) student 를 student의 score로 맵핑map() 을 해서 새로운 배열을 생성한다. (맵을 이용하게 되면 새로운 배열이 리턴 된다.) 학생들을 점수로 변환한다.
(2) filter() 를 이용한다. 받은 점수에서 다시 필터링 한다.
(3) sort() 는 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환한다. 만약 a-b 대신 b-a 로 정의하면 큰 순서부터 정렬된다.
(4) 리턴된 배열에 join() 을 써서 스트링으로 바꾼다.




reference
MDN-array dream-coding

profile
기억보단 기록을 ✨

0개의 댓글