obj의 타입이 배열인지 객체인지만 구분하면 굉장히 간단한 문제이다.
재귀함수 형식으로 호출해서 falsy한 값인지 판별하고 그대로 반환
type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue };
type Obj = Record<string, JSONValue> | Array<JSONValue>;
function compactObject(obj: Obj): Obj {
// 배열인 경우를 처리
if (Array.isArray(obj)) {
// 배열의 각 요소에 대해 재귀적으로 compactObject를 호출하고, falsy 값을 제거
return obj.reduce((acc: JSONValue[], cur: JSONValue) => {
const compacted = compactObject(cur as Obj);
if (Boolean(compacted)) acc.push(compacted);
return acc;
}, []);
}
// 객체인 경우를 처리
if (typeof obj === 'object' && obj !== null) {
return Object.entries(obj).reduce((acc: Record<string, JSONValue>, [key, value]) => {
// 각 값에 대해 재귀적으로 compactObject를 호출
const compacted = compactObject(value as Obj);
// falsy가 아닌 값만 결과 객체에 포함
if (Boolean(compacted)) acc[key] = compacted;
return acc;
}, {});
}
// 기본 타입(number, string, boolean, null)인 경우 그대로 반환
return obj;
}