배열을 입력받아 차례대로 배열의 첫 요소와 마지막 요소를 키와 값으로 하는 객체를 리턴해야 합니다.
패스
연이율을 입력받아 원금이 2배 이상이 될 때까지 걸리는 시간(년)을 리턴해야 합니다.
패스
수를 입력받아 2의 거듭제곱인지 여부를 리턴해야 합니다.
패스
문자열을 입력받아 문자열을 구성하는 각 단어의 첫 글자로 이루어진 문자열을 리턴해야 합니다.
function firstCharacter(str) {
// TODO: 여기에 코드를 작성합니다.
return str.split(' ').reduce((acc, cur) => acc += cur.charAt(0), '')
}
function firstReverse(str) {
// TODO: 여기에 코드를 작성합니다.
return Array.from(str).reverse().join('');
//or str.split('').reverse().join('');
}
문자열 메서드인 charAt()
, toUppserCase()
, slice()
활용법을 숙지하자
function letterCapitalize(str) {
// TODO: 여기에 코드를 작성합니다.
return str.split(' ').map(word => {
return word.charAt(0).toUpperCase() + word.slice(1);
}).join(' ')
}
2차원 배열(배열을 요소로 갖는 배열)을 입력받아 각 배열을 이용해 만든 객체를 리턴해야 합니다.
패스
문자열을 입력받아 해당 문자열에 등장하는 두 칸의 공백을 모두 한 칸의 공백으로 바꾼 문자열을 리턴해야 합니다.
배열을 순회하면서 flag 값에 따라 acc에 공백을 더할지 결정하는 방식으로 풀이하였다.
function convertDoubleSpaceToSingle(str) {
// TODO: 여기에 코드를 작성합니다.
let wasSpace = false;
return Array.from(str).reduce((acc, cur) => {
if (cur !== ' ') {
wasSpace = false;
return acc += cur;
}
if (wasSpace) {
return acc;
}
wasSpace = true;
return acc += cur;
}, '')
}
정리하면서 다시 풀면서 정규식으로 깔끔하게 성공했다.
처음엔 const pattern = /^a[\w\d\s]{3}b$/i
이라고 생각했는데, 이 경우 문장의 첫 부분과 끝부분이 a와 b로 되어야만 매칭시켜준다. 따라서 문장 가운데의 패턴은 검출하지 못한다.
정규식도 반복학습해서 기본적인 내용은 항상 능숙하게 사용할 수 있도록 메모리에 저장해놔야 한다.
function ABCheck(str) {
// code goes here
const pattern = /(a[\w\d\s]{3}b)|(b[\w\d\s]{3}a)/i
return pattern.test(str)
}
문자열을 입력받아 연속된 한자리 홀수 숫자 사이에 '-'를 추가한 문자열을 리턴해야 합니다.
내가 좋아하는 reduce로 풀었다. 반복문으로 푸는 것 보다 겉멋들어보임.
function insertDash(str) {
// TODO: 여기에 코드를 작성합니다.
let beforeOdd = false;
let nowOdd = false;
return Array.from(str).reduce((acc, cur) => {
nowOdd = cur % 2 !== 0
if (beforeOdd && nowOdd) acc += '-';
acc += cur;
beforeOdd = nowOdd;
return acc
}, '')
}
insert, update 사용법 익히기
UPDATE SET 함께 사용됨을 기억하자.
LIKE, NOT LIKE 모두 가능.
_ : ANY SINGLE CHAR PLACEHOLDER
[acs] : 정규식처럼 any of single chars between bracket
[a-f] : 범위도 가능
[^acf]: any single char not in bracket
datetime 형식도 MAX, MIN 연산 가능하다.
SELECT MAX(DATETIME) FROM ANIMAL_INS
ditinct 키워드를 어디에 쓰느냐 따라 count 결과가 달라진다.
위의 sql문은 distinct한 name을 대상으로 카운트를 보여준다.
아래의 sql문은 distinct의 대상이 카운트한 결과이므로 별 의미가 없는 distinct
SELECT count(distinct name) from animal_ins
SELECT distinct count(name) from animal_ins
date_format()
내장함수로 date객체의 출력형식을 바꿀 수 있다.
month()
로 date객체에서 월만 추출할 수 있다.
SELECT MEMBER_ID, MEMBER_NAME, GENDER, date_format(DATE_OF_BIRTH, '%Y-%m-%d') as DATE_OF_BIRTH FROM MEMBER_PROFILE
WHERE
GENDER = 'W' AND
MONTH(DATE_OF_BIRTH) = '3' AND
TLNO IS NOT NULL
ORDER BY MEMBER_ID ASC;
재구매 일어난 상품 찾기 - Programmers
답안을 보면 쉽게 이해되지만, 막상 작성하려니 잘 안된다.
GROUP BY는 다중으로 가능하며, 그룹지어진 대상에 대한 필터링은 HAVING 절에 기술한다.
SELECT USER_ID, PRODUCT_ID from online_sale group by user_id, product_id having count(*) > 1
ORDER BY USER_ID ASC, PRODUCT_ID DESC;
SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT FROM
ANIMAL_OUTS WHERE HOUR(DATETIME) BETWEEN 9 AND 19 GROUP BY HOUR(DATETIME) ORDER BY HOUR ASC
가격대 별 상품 개수 구하기
level2 였는데도 엄청 고민했고, 결국 해답을 봤다.
위의 쿼리는 구글링해서 적용한 쿼리인데, range를 하드코딩한 나쁜 답변이다.
select
case
when PRICE between 0 and 9999 then '0'
when PRICE between 10000 and 19999 then '10000'
when PRICE between 20000 and 29999 then '20000'
when PRICE between 30000 and 39999 then '30000'
end as `Range`,
count(1) as `Count`
from PRODUCT
group by `Range`;
programmers 해답에 나온 버림함수인 truncate()
를 멋지게 적용한 쿼리
truncate로 특정 범위의 가격을 일괄적으로 변환하고, group by를 적용해 그룹핑한 후 select로 조회했다. 배울점이 많은 쿼리문이었다.
SELECT TRUNCATE(PRICE, -4) AS PRICE_GROUP, COUNT(PRODUCT_ID) AS PRODUCTS
FROM PRODUCT
GROUP BY TRUNCATE(PRICE, -4)
ORDER BY PRICE_GROUP ASC;
group by와 join을 함께 사용해서 풀어야하는 문제였다.
아래는 실패한 내 쿼리문이다.
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES from REST_INFO
GROUP BY FOOD_TYPE HAVING FAVORITES = MIN(FAVORITES) ORDER BY FOOD_TYPE DESC;
정답을 봤다.
원본 테이블과, 원본테이블에서 음식 종류별로 그룹핑한 다음 favorites의 최댓값을 전달하는 테이블을 조인해서 조인한 테이블을 정렬해주었다.
정답을 보고도 고민한 부분은 SQL 문법 오류였는데, join 대상 테이블을 추출할 때 괄호로 감싸주고, 괄호 바깥에서 as로 aliasing한 붙인 부분이다. aliasing은 괄호 안쪽 테이블에 붙여주는 별칭이므로 괄호로 해당 group by 테이블을 감싸고 as로 aliasing 해주어야 한다.
SELECT A.FOOD_TYPE, A.REST_ID, A.REST_NAME, A.FAVORITES FROM REST_INFO AS A
INNER JOIN
(SELECT FOOD_TYPE, MAX(FAVORITES) AS FAVORITES FROM REST_INFO GROUP BY FOOD_TYPE) AS B
ON A.FOOD_TYPE = B.FOOD_TYPE AND A.FAVORITES = B.FAVORITES
ORDER BY A.FOOD_TYPE DESC
또 까먹음.. 어쩌냐 계속 반복해야지
핵심은 재귀호출하는 함수의 인자로 들어가는 배열과 인덱스를 적절히 가공해 주는것
// combinations
// 내부에서 반복하면서 재귀호출하는 핵심 부분의 코드다.
arr.forEach((fixed, index, origin) => {
const rest = [...origin.slice(index + 1)];
const combinations = getCombinations(res, n);
const subTotal = combinations.map(elem => [fixed, ...el]);
result.push(attatched)
})
// permutations
// 다른건 동일하지만 순서가 중요하므로 rest 배열은 해당되는 그 원소만 뺀 나머지 배열이 된다.
const rest = [...origin.slice(0, index), ...origin.slice(index + 1)];
아니,ㅋㅋㅋㅋㅋㅋㅋ 하루 공부량이 장난 없네요