오늘 새로 배운 내용을 간단하게 공부하여 적는 공간으로 잘못된 정보가 포함되어있을 수가 있습니다.
프로그래머스 lv0 - 구조 분해 할당 문제를 풀고 공부하게 되었다.
구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수로 담을 수 있게 하는 표현식이다.
solution = (box, n) => ~~(box[0]/n) * ~~(box[1]/n) * ~~(box[2]/n);
위의 코드는 필자가 구조 분해 할당 문제를 푼 코드이다.
box 는 총 세 개의 원소를 가진 배열인 매개변수로, box[0], box[1], box[2] 처럼 index 를 활용하여 box 의 원소에 접근하고 있다.
한줄로 코드를 제출한다면 위의 코드도 문제는 없겠지만, 추후에 프로젝트를 할 때나 문제를 풀이하는 코드의 양이 늘어나게 된다면 구조 분해 할당을 활용하여 좀 더 가독성 있고 간결하게 작성할 수 있을 것 같다.
var foo = ["one", "two", "three"];
var [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"
foo 배열을 분해하여 원소들을 red, yellow, green 에 순차적으로 할당한 것을 볼 수 있다.
var a, b;
[a, b] = [1, 2];
위와 같이 변수의 선언이 분리되어도 값이 잘 할당된다.
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
위와 같이 분해한 값이 undefined 라면 미리 설정해둔 기본값을 할당하게 할 수도 있다.
구조 분해를 활용하여 필자의 코드를 바꿔보도록 하자.
solution = (box, n) => {
const [width, length, height] = box;
return ~~(width/n) * ~~(length/n) ** ~~(width/n);
}
코드 자체는 길어졌지만 가독성이 눈에 띄게 좋아진게 보인다.
프로그래머스 코테 문제풀이를 하며 새로 배운 String 메소드들을 정리해보겠다.
repeat(count);
repeat
은 문자열 타입을 count
의 수만큼 반복하여 리턴해주는 메서드이다. 원래의 문자열은 바뀌지 않으니 참고하자.
let str = 'hello';
console.log(str.repeat(0)); // ''
console.log(str.repeat(3)); // 'hellohellohello'
console.log(str.repeat(2.6)); // 'hellohello'
repeat
의 매개변수 count
는 숫자 타입을 인자로 받는데, 이때 실수가 인자로 전달되면 소수점은 버림되어 처리된다.
0 을 인자로 받으면 빈 문자열을 반환한다.
endsWith(searchString)
endsWith(searchString, endPosition)
endsWith
은 문자열 타입이 searchString
로 끝나는지 평가하고 불리언 타입을 반환하는 메소드이다.
아래의 코드를 예시로, 'hello' 는 'llo' 로 끝나기 때문에 true 를, 'el' 로 끝나지 않기 때문에 false 를 반환한다.
let str = 'hello';
console.log(str.endsWith('llo')); // true
console.log(str.endsWith('el')); // false
console.log(str.endsWith('llo', 5)) // true
console.log(str.endsWith('llo', 6)) // false
매개변수 endPosition
은 필수로 값을 전달해야하는 매개변수는 아니지만, 만약 전달해야한다면 string.length 의 값을 전달해야만 true 를 반환한다.
string.length 이 아닌 값을 전달한다면 searchString 으로 문자열이 끝난다고 하더라도 false 를 반환한다.
trim()
trim
은 문자열의 시작과 끝에 존재하는 모든 공백을 잘라낸 문자열을 리턴한다. 마찬가지로 원래의 문자열을 변경하지는 않는다.
let str = ' Hello World ';
console.log(str.trim()); // 'Hello World'
시작과 끝의 공백만 잘라내지 중간에 존재하는 공백을 잘라내지는 않으니 참고하자.
String 메소드 모음과 마찬가지로, 프로그래머스 코테 문제풀이를 하며 새로 배운 연산자들을 정리해보겠다.
a << b
왼쪽 시프트 연산자 <<
는 왼쪽 피연산자의 값을 2진수로 바꾼 후, 오른쪽 피연산자 값의 비트만큼 왼쪽으로 이동시킨다.
9 (10진수): 00000000000000000000000000001001 (2진수)
9 << 2 (10진수): 00000000000000000000000000100100 (2진수) = 36 (10진수)
위와 같이, 왼쪽 피연산자인 9의 비트가 오른쪽 피연산자의 값인 2만큼 왼쪽으로 이동한 것을 볼 수 있다. 왼쪽으로 이동된 초과된 비트는 폐기되며, 오른쪽은 움직인 만큼 '0' 비트로 채워진다.
a << b
--> a * 2 ** b
위처럼 a << b
는 a * 2 ** b
의 값을 리턴한다.
따라서, 프로그래머스 lv0 - 세균 증식 문제는 비트 연산자를 통해 다음과 같이 간결하게 풀 수 있다.
const solution = (n, t) => n << t;
깊게 들어가면 조금 어려운 내용이 될 것 같아 간단하게만 짚고 넘어가겠다. 추후에 연산자를 더 공부하게 되면 그때 자세히 공부해보도록 하겠다.
XOR 연산자는 x 와 y 가 둘다 true 면 false 를, 둘다 false 면 true 를 반환한다. 이 특성을 이용하여 프로그래머스 lv0 - 배열의 길이에 따라 다른 연산하기 문제를 간단하게 해결할 수 있다.
const solution = (arr, n) => (arr.length % 2 === 0)
? arr.map((e, i) => ((i+1) % 2 === 0) ? e + n : e)
: arr.map((e, i) => ((i+1) % 2 !== 0) ? e + n : e);
정말 지저분하고 복잡해 보이는 필자의 코드이다.
문제의 요구사항을 정리해보겠다.
배열의 길이가 홀수 + 순회하고 있는 배열의 인덱스가 짝수 (!홀수)
--> 해당 요소에 매개변수 n을 더한다.
배열의 길이가 짝수 + 순회하고 있는 배열의 인덱스가 홀수 (!짝수)
--> 해당 요소에 매개변수 n을 더한다.
이걸 적용해서 새로운 배열을 리턴.
이걸 XOR 연산자를 활용하면 정말 쉽게 문제를 해결할 수 있었다.
const solution = (arr, n) => arr.map((e, i) => (arr.length % 2 === 0 ^ i % 2 === 0) ? e += n : e);
약간의 설명을 덧붙여보자면,
[2, 4, 5, 6, 7] 의 배열을 arr 에 인자로 전달한다고 가정해보자.
추후에 XOR 을 활용할 수 있는 문제가 또 나왔으면 좋겠다.
for (variable in object)
statement
for...in
문은 객체의 프로퍼티를 순회할 때 주로 사용된다.
const object = { a: 1, b: 2, c: 3 };
for (const property in object) {
console.log(`${property}: ${object[property]}`);
}
// Expected output:
// "a: 1"
// "b: 2"
// "c: 3"
다음과 같이 프로퍼티의 key 를 variable
매개변수로 전달하여, 객체의 프로퍼티에 접근할 수 있다.
배열도 객체이기 때문에 for...in
을 활용할 수 있으며, 이때 배열의 각 요소를 프로퍼티로 인식하여 key 는 요소의 index, value 는 해당 요소의 값으로 평가된다.
const arr = [1, 2, 3]
for (const n in arr) {
console.log(`${n}: ${arr[n]}`);
}
// "0: 1"
// "1: 2"
// "2: 3"
자바스크립트 Deep Dive 에 따르면, for...in 문으로 배열을 순회할 경우, 배열도 객체이므로 상속받은 프로퍼티가 포함될 수도 있다고 하여 일반적인 for 문, for...of 혹은 forEach 를 사용하기를 권장하고 있다.
for (variable of iterable)
statement
for...of
문은 배열을 순회할 때 주로 사용된다.
const array1 = ['a', 'b', 'c'];
for (const element of array1) {
console.log(element);
}
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
매개변수 variable
에는 변수를 선언하여 그 변수를 통해 배열의 요소에 접근할 수 있다.
Math.max()
Math.max(value0)
Math.max(value0, value1)
Math.max(value0, value1, /* … ,*/ valueN)
매개변수에 원하는 만큼의 숫자값을 전달하여 인자로 전달된 값들 중 가장 큰 값을 리턴하는 메소드이다.
console.log(Math.max(9, 3, 2));
// Expected output: 9
console.log(Math.max(-1, 8, -2));
// Expected output: 8
const array1 = [1, 3, 2];
console.log(Math.max(...array1));
// Expected output: 3
위와 같이 스프레드 연산자를 사용하여 배열을 분해하여 max 메소드를 적용할 수도 있다.
Math.sqrt(x)
매개변수 x 에 전달된 인자의 제곱근을 반환하는 메소드다.
Math.sqrt(9); // 3
Math.sqrt(2); // 1.4142135623730951
Math.sqrt(9) === 9 ** 1/2
숫자타입의 값에 직접 1/2 를 제곱한 값과 일치 비교를 하면 false 가 나온다.
0.1 + 0.2 === 0.3 이 false 인 것과 비슷한 맥락으로, 이는 추후에 자세히 포스팅 하도록 하겠다.
정확한 제곱근 값을 리턴하려면 sqrt 메소드를 사용하도록 하자.