์์ ๋ฐ์ดํฐ
const data = {
student: {
info: {
roll_number: "10",
scores: {
math: 95
}
},
class: "1st"
},
teacher: {
name: "Mr. Smith",
school: "ABC"
},
roll_number: "wrong"
};
input: `path = 'student.info.roll_number'`
output: `"10"`
input: `path = 'student.class'`
output: `"1st"`
input: `path = 'roll_number'`
output: `"wrong"`
ํจ์ ์์ฑํ๊ธฐ
function getObjectValue(obj, path) {
}
๋ฐฉ๋ฒ1.
function getObjectValue(obj, path) {
const pathArr = path.split('.')
let current = obj;
for (const path of pathArr) {
current = current[path]
if (!current) return undefined
}
return current
}
ํฌ์ธํธ๋ ๊ฐ path๋ฅผ for๋ก ์ํํ ๋ ๋ง๋ค ์ฐพ์ value ๊ฐ์ ์ ์ฅํ๋ obj(์ ์ฝ๋์์๋ current ๋ณ์)๊ฐ ํ์ํ๋ค.
๊ทธ๋์ผ nested object ๊ตฌ์กฐ์์ ๊ฐ์ฅ ๋จผ์ ๋์ค๋ path๋ฅผ ์ฐพ์์, current ์ ๊ณ์ ์ฌ ํ ๋นํด๊ฐ๋ฉด์ ์ํ๋ value ๊ฐ์ ์ฐพ์ ์ ์๋ค.
์๋ฅผ๋ค๋ฉด path๊ฐ `'student.info.roll_number'` ๋ผ๋ฉด ์๋์ ๊ฐ๋ค.
current ๋ณ์ ๊ฐ ๋๋ฒ๊น
for ์ด์
{
student: { info: { roll_number: '10', scores: { math: 95 } }, class: '1st' },
teacher: { name: 'Mr. Smith', school: 'ABC' },
roll_number: 'wrong'
}
current[student]
{ info: { roll_number: '10', scores: { math: 95 } }, class: '1st' }
current[info]
{ roll_number: '10', scores: { math: 95 } }
current[roll_number]
10
๋ฐฉ๋ฒ2.
function getObjectValue(obj, path) {
const pathArr = path.split('.')
return pathArr.reduce((acc, curr) => {
return acc? acc[curr] : undefined
}, obj)
}
๋ฐฉ๋ฒ1๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก path๋ฅผ ์ฐ์ . ๋จ์๋ก ๋๋ array๋ฅผ ๊ธฐ์ค์ผ๋ก loop๋ฅผ ๋๋ฆฐ๋ค.
์ข ๋ js์ค๋ฌ์ด ๊ณ ์ฐจํจ์์ธ reduce ํจ์๋ฅผ ์ด์ฉํด์ ํจ์ฌ ์งง์ ์ฝ๋๋ฅผ ํ ์ ์๋ค. ์ฒ์ initial value๋ฅผ input์ผ๋ก ๋ฐ๋ obj ๋ก ์ค์ ํ๊ณ , ๊ฐ path ์คํธ๋ง ๊ฐ์ `curr`๋ผ๋ reduce ํจ์ ๋ด๋ถ์ current value ๋ณ์๋ก ๋ด์์ค๋ค. path๊ฐ ๋ค ๋๋๊น์ง path๋ก ์ฐพ์ ๊ฐ์ฒด๊ฐ์ acc๋ผ๋ ๋์ ๋ณ์์ ์ฌํ ๋นํด์ฃผ๋ ๊ฑฐ๋ค.
์ฌ๊ธฐ์ ํฌ์ธํธ๋ 4๋ฒ์งธ ์ค์ `acc`๊ฐ ์กด์ฌํ๋์ง๋ฅผ ํ์ธํ์ง ์์ผ๋ฉด, TypeError: Cannot read properties of undefined (reading 'path') ์๋ฌ๊ฐ ๋๋ค. ๋ฐ๋ผ์ acc ๋ผ๋ ๋์ ๊ฐ์ด ์์ผ๋ฉด ๋ฐ๋ก undefined๋ฅผ ๋ฆฌํดํด์ค์ผ ํ๋ค.
์๋ฅผ๋ค์ด `path = 'nonexistent.path'` ์์์ผ๋, reduce ํจ์ ๋ด๋ถ์ acc์ curr๋ฅผ ๋๋ฒ๊น ํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
1st loop
๋์ acc
{
student: { info: { roll_number: '10', scores: [Object] }, class: '1st' },
teacher: { name: 'Mr. Smith', school: 'ABC' },
roll_number: 'wrong'
}
ํ์ฌ curr
nonexistent
2nd loop
๋์ acc
undefined
ํ์ฌ curr
path
๋๋ฒ์งธ ๋ฃจํ๋ฅผ ๋๋ ์ด๋ฏธ๊ฐ์ง๊ณ ์๋ ๋์ acc๊ฐ์ undefined ๊ฐ์ธ๋ฐ ์ฌ๊ธฐ๋ค path ๋ผ๋ ํค๊ฐ์ ์ฐพ์ผ๋ ค๋ ์๋ฌ๊ฐ ๋๋ค.
๋ฐฉ๋ฒ1, 2 ๋ชจ๋ Time Complexity๋ `O(N)`์ด ๋๋ค.
ํ ์คํธ ์ฝ๋
function testGetObjectValue() {
const data = {
student: {
info: {
roll_number: "10",
scores: {
math: 95
}
},
class: "1st"
},
teacher: {
name: "Mr. Smith",
school: "ABC"
},
roll_number: "wrong"
};
const tests = [
{ path: 'student.info.roll_number', expected: "10" },
{ path: 'student.class', expected: "1st" },
{ path: 'teacher.name', expected: "Mr. Smith" },
{ path: 'teacher.school', expected: "ABC" },
{ path: 'student.info.scores.math', expected: 95 },
{ path: 'roll_number', expected: "wrong" },
{ path: 'student.grade', expected: undefined },
{ path: 'student.info.roll_number.number', expected: undefined },
{ path: 'student.info', expected: data.student.info },
{ path: 'nonexistent.path', expected: undefined },
];
let passed = 0;
for (const { path, expected } of tests) {
const result = getObjectValue(data, path);
const isEqual = JSON.stringify(result) === JSON.stringify(expected);
console.log(
isEqual
? `โ
Passed: ${path} => ${JSON.stringify(result)}`
: `โ Failed: ${path} => ${JSON.stringify(result)}, expected ${JSON.stringify(expected)}`
);
if (isEqual) passed++;
}
console.log(`\n๐งช ${passed}/${tests.length} tests passed.`);
}
// ์คํ
testGetObjectValue();
'JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JSON.stringify() | JSON.parse() | json() (3) | 2024.09.19 |
---|---|
api ์์ฐจ์ ์คํ | catch (err) vs catch | throw error vs return error (0) | 2024.05.22 |
TypeScript index signature ์ธ๋ฑ์ค ์๊ทธ๋์ณ (0) | 2023.09.08 |
JS ๋ฐฐ์ด ๊ฐ์ฒด์์ ์์ immutable, mutable (0) | 2023.06.26 |
JS parseInt() vs Number() (0) | 2022.11.13 |