์คํธ๋ฆผ ๊ตฌ์ฑ์ ํตํด JavaScript ์ดํฐ๋ ์ดํฐ ํฌํผ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ํ์ฉํ์ธ์. ํจ์จ์ ์ด๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์ํด ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.
JavaScript ์ดํฐ๋ ์ดํฐ ํฌํผ ์คํธ๋ฆผ ๊ตฌ์ฑ: ๋ณต์กํ ์คํธ๋ฆผ ๋น๋ฉ ๋ง์คํฐํ๊ธฐ
ํ๋ JavaScript ๊ฐ๋ฐ์์ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๊ธฐ์กด์ ๋ฐฐ์ด ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง, ๋ณต์กํ ๋ณํ์ ๋ค๋ฃฐ ๋๋ ๋ฒ๊ฑฐ๋กญ๊ณ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง ์ ์์ต๋๋ค. JavaScript ์ดํฐ๋ ์ดํฐ ํฌํผ๋ ๋ ์ฐ์ํ๊ณ ๊ฐ๋ ฅํ ํด๊ฒฐ์ฑ ์ ์ ๊ณตํ์ฌ, ํํ๋ ฅ ์๊ณ ๊ตฌ์ฑ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์คํธ๋ฆผ์ ๋ง๋ค ์ ์๊ฒ ํด์ค๋๋ค. ์ด ๊ธ์์๋ ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์ธ๊ณ๋ฅผ ํ๊ตฌํ๊ณ , ์คํธ๋ฆผ ๊ตฌ์ฑ์ ํ์ฉํ์ฌ ์ ๊ตํ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
JavaScript ์ดํฐ๋ ์ดํฐ ํฌํผ๋ ๋ฌด์์ธ๊ฐ์?
์ดํฐ๋ ์ดํฐ ํฌํผ๋ ์ดํฐ๋ ์ดํฐ์ ์ ๋๋ ์ดํฐ์ ๋ํด ์๋ํ๋ ๋ฉ์๋ ์งํฉ์ผ๋ก, ํจ์ํ์ด๊ณ ์ ์ธ์ ์ธ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์กฐ์ํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ ๋จ๊ณ๋ฅผ ์ฆ์ ํ๊ฐํ๋ ๊ธฐ์กด์ ๋ฐฐ์ด ๋ฉ์๋์ ๋ฌ๋ฆฌ, ์ดํฐ๋ ์ดํฐ ํฌํผ๋ ์ง์ฐ ํ๊ฐ(lazy evaluation)๋ฅผ ์ฑํํ์ฌ ํ์ํ ๋๋ง ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ ํนํ ๋์ฉ๋ ๋ฐ์ดํฐ์ ์ ๋ค๋ฃฐ ๋ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์ฃผ์ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- map: ์คํธ๋ฆผ์ ๊ฐ ์์๋ฅผ ๋ณํํฉ๋๋ค.
- filter: ์ฃผ์ด์ง ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์์๋ฅผ ์ ํํฉ๋๋ค.
- take: ์คํธ๋ฆผ์ ์ฒซ 'n'๊ฐ ์์๋ฅผ ๋ฐํํฉ๋๋ค.
- drop: ์คํธ๋ฆผ์ ์ฒซ 'n'๊ฐ ์์๋ฅผ ๊ฑด๋๋๋๋ค.
- flatMap: ๊ฐ ์์๋ฅผ ์คํธ๋ฆผ์ ๋งคํํ ํ ๊ฒฐ๊ณผ๋ฅผ ํํํํฉ๋๋ค.
- reduce: ์คํธ๋ฆผ์ ์์๋ค์ ๋จ์ผ ๊ฐ์ผ๋ก ๋์ ํฉ๋๋ค.
- forEach: ๊ฐ ์์์ ๋ํด ์ ๊ณต๋ ํจ์๋ฅผ ํ ๋ฒ ์คํํฉ๋๋ค. (์ง์ฐ ์คํธ๋ฆผ์์๋ ์ฃผ์ํด์ ์ฌ์ฉํ์ธ์!)
- toArray: ์คํธ๋ฆผ์ ๋ฐฐ์ด๋ก ๋ณํํฉ๋๋ค.
์คํธ๋ฆผ ๊ตฌ์ฑ ์ดํดํ๊ธฐ
์คํธ๋ฆผ ๊ตฌ์ฑ์ ์ฌ๋ฌ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ํจ๊ป ์ฐ๊ฒฐํ์ฌ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๋ง๋๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ๊ฐ ํฌํผ๋ ์ด์ ํฌํผ์ ์ถ๋ ฅ์ ๋ํด ์๋ํ์ฌ, ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ๋ฐฉ์์ผ๋ก ๋ณต์กํ ๋ณํ์ ๊ตฌ์ถํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ, ํ ์คํธ ์ฉ์ด์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ์ ์ฆ์ง์ํต๋๋ค.
ํต์ฌ ์์ด๋์ด๋ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๋๊น์ง ๋จ๊ณ๋ณ๋ก ๋ณํํ๋ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ง๋๋ ๊ฒ์ ๋๋ค.
๊ฐ๋จํ ์คํธ๋ฆผ ๋ง๋ค๊ธฐ
๊ธฐ๋ณธ์ ์ธ ์์ ๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค. ์ซ์ ๋ฐฐ์ด์ด ์๊ณ , ์ง์๋ฅผ ๊ฑธ๋ฌ๋ธ ๋ค์ ๋จ์ ํ์๋ฅผ ์ ๊ณฑํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// ๊ธฐ์กด ๋ฐฉ์ (๊ฐ๋
์ฑ์ด ๋จ์ด์ง)
const squaredOdds = numbers
.filter(num => num % 2 !== 0)
.map(num => num * num);
console.log(squaredOdds); // ์ถ๋ ฅ: [1, 9, 25, 49, 81]
์ด ์ฝ๋๋ ์๋ํ์ง๋ง, ๋ณต์ก์ฑ์ด ์ฆ๊ฐํจ์ ๋ฐ๋ผ ์ฝ๊ณ ์ ์ง๋ณด์ํ๊ธฐ๊ฐ ๋ ์ด๋ ค์์ง ์ ์์ต๋๋ค. ์ด์ ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์คํธ๋ฆผ ๊ตฌ์ฑ์ ์ฌ์ฉํ์ฌ ๋ค์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
function* numberGenerator(array) {
for (const item of array) {
yield item;
}
}
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const stream = numberGenerator(numbers);
const squaredOddsStream = {
*[Symbol.iterator]() {
for (const num of stream) {
if (num % 2 !== 0) {
yield num * num;
}
}
}
}
const squaredOdds = [...squaredOddsStream];
console.log(squaredOdds); // ์ถ๋ ฅ: [1, 9, 25, 49, 81]
์ด ์์ ์์ `numberGenerator`๋ ์ ๋ ฅ ๋ฐฐ์ด์ ๊ฐ ์ซ์๋ฅผ ์์ฑ(yield)ํ๋ ์ ๋๋ ์ดํฐ ํจ์์ ๋๋ค. `squaredOddsStream`์ ์ฐ๋ฆฌ์ ๋ณํ ์ญํ ์ ํ๋ฉฐ, ํ์๋ง ํํฐ๋งํ๊ณ ์ ๊ณฑํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ๋ฐ์ดํฐ ์์ค์ ๋ณํ ๋ก์ง์ ๋ถ๋ฆฌํฉ๋๋ค.
๊ณ ๊ธ ์คํธ๋ฆผ ๊ตฌ์ฑ ๊ธฐ๋ฒ
์ด์ ๋ ๋ณต์กํ ์คํธ๋ฆผ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ๊ณ ๊ธ ๊ธฐ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. ์ฌ๋ฌ ๋ณํ ์ฐ๊ฒฐํ๊ธฐ
์ฌ๋ฌ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ํจ๊ป ์ฐ๊ฒฐํ์ฌ ์ผ๋ จ์ ๋ณํ์ ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ํ ๊ฐ์ฒด ๋ชฉ๋ก์ด ์๊ณ , ๊ฐ๊ฒฉ์ด $10 ๋ฏธ๋ง์ธ ์ ํ์ ํํฐ๋งํ ๋ค์, ๋จ์ ์ ํ์ 10% ํ ์ธ์ ์ ์ฉํ๊ณ , ๋ง์ง๋ง์ผ๋ก ํ ์ธ๋ ์ ํ์ ์ด๋ฆ์ ์ถ์ถํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค.
function* productGenerator(products) {
for (const product of products) {
yield product;
}
}
const products = [
{ name: "Laptop", price: 1200 },
{ name: "Mouse", price: 8 },
{ name: "Keyboard", price: 50 },
{ name: "Monitor", price: 300 },
];
const stream = productGenerator(products);
const discountedProductNamesStream = {
*[Symbol.iterator]() {
for (const product of stream) {
if (product.price >= 10) {
const discountedPrice = product.price * 0.9;
yield { name: product.name, price: discountedPrice };
}
}
}
};
const productNames = [...discountedProductNamesStream].map(product => product.name);
console.log(productNames); // ์ถ๋ ฅ: [ 'Laptop', 'Keyboard', 'Monitor' ]
์ด ์์ ๋ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ์ฐ๊ฒฐํ์ฌ ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๋ง๋๋ ๊ฐ๋ ฅํจ์ ๋ณด์ฌ์ค๋๋ค. ๋จผ์ ๊ฐ๊ฒฉ์ ๊ธฐ์ค์ผ๋ก ์ ํ์ ํํฐ๋งํ๊ณ , ํ ์ธ์ ์ ์ฉํ ๋ค์, ๋ง์ง๋ง์ผ๋ก ์ด๋ฆ์ ์ถ์ถํฉ๋๋ค. ๊ฐ ๋จ๊ณ๋ ๋ช ํํ๊ฒ ์ ์๋์ด ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค.
2. ๋ณต์กํ ๋ก์ง์ ์ํ ์ ๋๋ ์ดํฐ ํจ์ ์ฌ์ฉ
๋ ๋ณต์กํ ๋ณํ์ ์ํด ์ ๋๋ ์ดํฐ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ก์ง์ ์บก์ํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ ๊นจ๋ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ๊ฐ์ฒด ์คํธ๋ฆผ์ด ์๊ณ , ํน์ ๊ตญ๊ฐ(์: ๋ ์ผ)์ ๊ฑฐ์ฃผํ๋ฉฐ ํ๋ฆฌ๋ฏธ์ ๊ตฌ๋ ์ ๊ฐ์ง ์ฌ์ฉ์์ ์ด๋ฉ์ผ ์ฃผ์๋ฅผ ์ถ์ถํ๊ณ ์ถ์ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ด ์๋ค.
function* userGenerator(users) {
for (const user of users) {
yield user;
}
}
const users = [
{ name: "Alice", email: "alice@example.com", country: "USA", subscription: "premium" },
{ name: "Bob", email: "bob@example.com", country: "Germany", subscription: "basic" },
{ name: "Charlie", email: "charlie@example.com", country: "Germany", subscription: "premium" },
{ name: "David", email: "david@example.com", country: "UK", subscription: "premium" },
];
const stream = userGenerator(users);
const premiumGermanEmailsStream = {
*[Symbol.iterator]() {
for (const user of stream) {
if (user.country === "Germany" && user.subscription === "premium") {
yield user.email;
}
}
}
};
const premiumGermanEmails = [...premiumGermanEmailsStream];
console.log(premiumGermanEmails); // ์ถ๋ ฅ: [ 'charlie@example.com' ]
์ด ์์ ์์ ์ ๋๋ ์ดํฐ ํจ์ `premiumGermanEmails`๋ ํํฐ๋ง ๋ก์ง์ ์บก์ํํ์ฌ ์ฝ๋๋ฅผ ๋ ์ฝ๊ธฐ ์ฝ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ข๊ฒ ๋ง๋ญ๋๋ค.
3. ๋น๋๊ธฐ ์์ ์ฒ๋ฆฌ
์ดํฐ๋ ์ดํฐ ํฌํผ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ ๋ฐ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ API๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ ํนํ ์ ์ฉํฉ๋๋ค.
API์์ ์ฌ์ฉ์ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ํจ์๊ฐ ์๊ณ , ๋นํ์ฑ ์ฌ์ฉ์๋ฅผ ํํฐ๋งํ ๋ค์ ๊ทธ๋ค์ ์ด๋ฆ์ ์ถ์ถํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค.
async function* fetchUsers() {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const users = await response.json();
for (const user of users) {
yield user;
}
}
async function processUsers() {
const stream = fetchUsers();
const activeUserNamesStream = {
async *[Symbol.asyncIterator]() {
for await (const user of stream) {
if (user.id <= 5) {
yield user.name;
}
}
}
};
const activeUserNames = [];
for await (const name of activeUserNamesStream) {
activeUserNames.push(name);
}
console.log(activeUserNames);
}
processUsers();
// ๊ฐ๋ฅํ ์ถ๋ ฅ (API ์๋ต์ ๋ฐ๋ผ ์์๊ฐ ๋ค๋ฅผ ์ ์์):
// [ 'Leanne Graham', 'Ervin Howell', 'Clementine Bauch', 'Patricia Lebsack', 'Chelsey Dietrich' ]
์ด ์์ ์์ `fetchUsers`๋ API์์ ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ ํจ์์ ๋๋ค. ์ฐ๋ฆฌ๋ `Symbol.asyncIterator`์ `for await...of`๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ฌ์ฉ์ ์คํธ๋ฆผ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ฐ๋ณตํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ฐ๋ชจ ๋ชฉ์ ์ผ๋ก ๋จ์ํ๋ ๊ธฐ์ค(`user.id <= 5`)์ ๋ฐ๋ผ ์ฌ์ฉ์๋ฅผ ํํฐ๋งํ๊ณ ์์์ ์ฐธ๊ณ ํ์ธ์.
์คํธ๋ฆผ ๊ตฌ์ฑ์ ์ด์
์ดํฐ๋ ์ดํฐ ํฌํผ์ ํจ๊ป ์คํธ๋ฆผ ๊ตฌ์ฑ์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ์ด์ ์ด ์์ต๋๋ค:
- ๊ฐ๋ ์ฑ ํฅ์: ์ ์ธ์ ์คํ์ผ์ ์ฝ๋๋ฅผ ์ดํดํ๊ณ ์ถ๋ก ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
- ์ ์ง๋ณด์์ฑ ํฅ์: ๋ชจ๋์ ์ค๊ณ๋ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ณ ๋๋ฒ๊น ์ ๋จ์ํํฉ๋๋ค.
- ์ฑ๋ฅ ํฅ์: ์ง์ฐ ํ๊ฐ๋ ๋ถํ์ํ ๊ณ์ฐ์ ํผํ๊ฒ ํ์ฌ, ํนํ ๋์ฉ๋ ๋ฐ์ดํฐ์ ์์ ์ฑ๋ฅ ์ด๋์ ๊ฐ์ ธ์ต๋๋ค.
- ํ ์คํธ ์ฉ์ด์ฑ ํฅ์: ๊ฐ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ ์ ์์ด ์ฝ๋ ํ์ง์ ๋ณด์ฅํ๊ธฐ๊ฐ ๋ ์ฝ์ต๋๋ค.
- ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ: ์คํธ๋ฆผ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์์ ๊ตฌ์ฑํ๊ณ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ค์ฉ์ ์ธ ์์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ์ฌ์ฉํ ์คํธ๋ฆผ ๊ตฌ์ฑ์ ๋ค์์ ํฌํจํ ๊ด๋ฒ์ํ ์๋๋ฆฌ์ค์ ์ ์ฉ๋ ์ ์์ต๋๋ค:
- ๋ฐ์ดํฐ ๋ณํ: ๋ค์ํ ์์ค์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฆฌ, ํํฐ๋ง ๋ฐ ๋ณํํฉ๋๋ค.
- ๋ฐ์ดํฐ ์ง๊ณ: ํต๊ณ ๊ณ์ฐ, ๋ฐ์ดํฐ ๊ทธ๋ฃนํ ๋ฐ ๋ณด๊ณ ์ ์์ฑ์ ํฉ๋๋ค.
- ์ด๋ฒคํธ ์ฒ๋ฆฌ: ์ฌ์ฉ์ ์ธํฐํ์ด์ค, ์ผ์ ๋๋ ๊ธฐํ ์์คํ ์ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํฉ๋๋ค.
- ๋น๋๊ธฐ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ: API, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ ๊ธฐํ ๋น๋๊ธฐ ์์ค์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- ์ค์๊ฐ ๋ฐ์ดํฐ ๋ถ์: ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ๋ถ์ํ์ฌ ์ถ์ธ์ ์ด์ ์งํ๋ฅผ ๊ฐ์งํฉ๋๋ค.
์์ 1: ์น์ฌ์ดํธ ํธ๋ํฝ ๋ฐ์ดํฐ ๋ถ์
๋ก๊ทธ ํ์ผ์์ ์น์ฌ์ดํธ ํธ๋ํฝ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๊ณ ์๋ค๊ณ ์์ํด ๋ณด์ธ์. ํน์ ์๊ฐ ๋ด์ ํน์ ํ์ด์ง์ ์ ์ํ ๊ฐ์ฅ ๋น๋ฒํ IP ์ฃผ์๋ฅผ ์๋ณํ๊ณ ์ถ์ต๋๋ค.
// ๋ก๊ทธ ํ์ผ์ ์ฝ๊ณ ๊ฐ ๋ก๊ทธ ํญ๋ชฉ์ ์์ฑํ๋ ํจ์๊ฐ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค
async function* readLogFile(filePath) {
// ๋ก๊ทธ ํ์ผ์ ํ ์ค์ฉ ์ฝ์ด
// ๊ฐ ๋ก๊ทธ ํญ๋ชฉ์ ๋ฌธ์์ด๋ก ์์ฑํ๋ ๊ตฌํ
// ๊ฐ๋จํ๊ฒ ์ด ์์ ์์๋ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์(mock) ์ฒ๋ฆฌํ๊ฒ ์ต๋๋ค.
const logEntries = [
"2024-01-01 10:00:00 - IP:192.168.1.1 - Page:/home",
"2024-01-01 10:00:05 - IP:192.168.1.2 - Page:/about",
"2024-01-01 10:00:10 - IP:192.168.1.1 - Page:/home",
"2024-01-01 10:00:15 - IP:192.168.1.3 - Page:/contact",
"2024-01-01 10:00:20 - IP:192.168.1.1 - Page:/home",
"2024-01-01 10:00:25 - IP:192.168.1.2 - Page:/about",
"2024-01-01 10:00:30 - IP:192.168.1.4 - Page:/home",
];
for (const entry of logEntries) {
yield entry;
}
}
async function analyzeTraffic(filePath, page, startTime, endTime) {
const logStream = readLogFile(filePath);
const ipAddressesStream = {
async *[Symbol.asyncIterator]() {
for await (const entry of logStream) {
const timestamp = new Date(entry.substring(0, 19));
const ip = entry.match(/IP:(.*?)-/)?.[1].trim();
const accessedPage = entry.match(/Page:(.*)/)?.[1].trim();
if (
timestamp >= startTime &&
timestamp <= endTime &&
accessedPage === page
) {
yield ip;
}
}
}
};
const ipCounts = {};
for await (const ip of ipAddressesStream) {
ipCounts[ip] = (ipCounts[ip] || 0) + 1;
}
const sortedIpAddresses = Object.entries(ipCounts)
.sort(([, countA], [, countB]) => countB - countA)
.map(([ip, count]) => ({ ip, count }));
console.log("Top IP Addresses accessing " + page + ":", sortedIpAddresses);
}
// ์ฌ์ฉ ์์ :
const filePath = "/path/to/logfile.log";
const page = "/home";
const startTime = new Date("2024-01-01 10:00:00");
const endTime = new Date("2024-01-01 10:00:30");
analyzeTraffic(filePath, page, startTime, endTime);
// ์์ ์ถ๋ ฅ (๋ชจ์ ๋ฐ์ดํฐ ๊ธฐ์ค):
// Top IP Addresses accessing /home: [ { ip: '192.168.1.1', count: 3 }, { ip: '192.168.1.4', count: 1 } ]
์ด ์์ ๋ ์คํธ๋ฆผ ๊ตฌ์ฑ์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๊ธฐ์ค์ ๋ฐ๋ผ ํญ๋ชฉ์ ํํฐ๋งํ๋ฉฐ, ๊ฒฐ๊ณผ๋ฅผ ์ง๊ณํ์ฌ ๊ฐ์ฅ ๋น๋ฒํ IP ์ฃผ์๋ฅผ ์๋ณํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ด ์์ ์ ๋น๋๊ธฐ์ ํน์ฑ์ ์ค์ ๋ก๊ทธ ํ์ผ ์ฒ๋ฆฌ์ ์ด์์ ์ ๋๋ค.
์์ 2: ๊ธ์ต ๊ฑฐ๋ ์ฒ๋ฆฌ
๊ธ์ต ๊ฑฐ๋ ์คํธ๋ฆผ์ด ์๊ณ , ์๊ณ ๊ธ์ก์ ์ด๊ณผํ๊ฑฐ๋ ๊ณ ์ํ ๊ตญ๊ฐ์์ ๋ฐ์ํ ๊ฒ๊ณผ ๊ฐ์ ํน์ ๊ธฐ์ค์ ๋ฐ๋ผ ์์ฌ์ค๋ฌ์ด ๊ฑฐ๋๋ฅผ ์๋ณํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ์ด๊ฒ์ด ๊ตญ์ ๊ท์ ์ ์ค์ํด์ผ ํ๋ ๊ธ๋ก๋ฒ ๊ฒฐ์ ์์คํ ์ ์ผ๋ถ๋ผ๊ณ ์์ํด ๋ณด์ธ์.
function* transactionGenerator(transactions) {
for (const transaction of transactions) {
yield transaction;
}
}
const transactions = [
{ id: 1, amount: 100, currency: "USD", country: "USA", date: "2024-01-01" },
{ id: 2, amount: 5000, currency: "EUR", country: "Russia", date: "2024-01-02" },
{ id: 3, amount: 200, currency: "GBP", country: "UK", date: "2024-01-03" },
{ id: 4, amount: 10000, currency: "JPY", country: "China", date: "2024-01-04" },
];
const highRiskCountries = ["Russia", "North Korea"];
const thresholdAmount = 7500;
const stream = transactionGenerator(transactions);
const suspiciousTransactionsStream = {
*[Symbol.iterator]() {
for (const transaction of stream) {
if (
transaction.amount > thresholdAmount ||
highRiskCountries.includes(transaction.country)
) {
yield transaction;
}
}
}
};
const suspiciousTransactions = [...suspiciousTransactionsStream];
console.log("Suspicious Transactions:", suspiciousTransactions);
// ์ถ๋ ฅ:
// Suspicious Transactions: [
// { id: 2, amount: 5000, currency: 'EUR', country: 'Russia', date: '2024-01-02' },
// { id: 4, amount: 10000, currency: 'JPY', country: 'China', date: '2024-01-04' }
// ]
์ด ์์ ๋ ๋ฏธ๋ฆฌ ์ ์๋ ๊ท์น์ ๋ฐ๋ผ ๊ฑฐ๋๋ฅผ ํํฐ๋งํ๊ณ ์ ์ฌ์ ์ผ๋ก ์ฌ๊ธฐ์ฑ ํ๋์ ์๋ณํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. `highRiskCountries` ๋ฐฐ์ด๊ณผ `thresholdAmount`๋ ๊ตฌ์ฑ ๊ฐ๋ฅํ๋ฏ๋ก ๋ณํํ๋ ๊ท์ ๋ฐ ์ํ ํ๋กํ์ ์๋ฃจ์ ์ ์ ์์ํฌ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ธ ํจ์ ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก
- ๋ถ์ ํจ๊ณผ ํผํ๊ธฐ: ์์ธก ๊ฐ๋ฅํ ๋์์ ๋ณด์ฅํ๊ธฐ ์ํด ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ด์ ๋ถ์ ํจ๊ณผ๋ฅผ ์ต์ํํ์ธ์.
- ์ฐ์ํ๊ฒ ์ค๋ฅ ์ฒ๋ฆฌํ๊ธฐ: ์คํธ๋ฆผ ์ค๋จ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์ธ์.
- ์ฑ๋ฅ ์ต์ ํ: ์ ์ ํ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ์ ํํ๊ณ ๋ถํ์ํ ๊ณ์ฐ์ ํผํ์ธ์.
- ์ค๋ช ์ ์ธ ์ด๋ฆ ์ฌ์ฉ: ์ฝ๋ ๋ช ํ์ฑ์ ํฅ์์ํค๊ธฐ ์ํด ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์๋ฏธ ์๋ ์ด๋ฆ์ ๋ถ์ฌํ์ธ์.
- ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ณ ๋ ค: ๋ ๊ณ ๊ธ ์คํธ๋ฆผ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ํด RxJS ๋๋ Highland.js์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ํด ๋ณด์ธ์.
- ๋ถ์ ํจ๊ณผ๋ฅผ ์ํด forEach๋ฅผ ๋จ์ฉํ์ง ๋ง์ธ์. `forEach` ํฌํผ๋ ์ฆ์ ์คํ๋์ด ์ง์ฐ ํ๊ฐ์ ์ด์ ์ ๊นจ๋จ๋ฆด ์ ์์ต๋๋ค. ๋ถ์ ํจ๊ณผ๊ฐ ์ ๋ง๋ก ํ์ํ ๊ฒฝ์ฐ `for...of` ๋ฃจํ๋ ๋ค๋ฅธ ๋ฉ์ปค๋์ฆ์ ์ ํธํ์ธ์.
๊ฒฐ๋ก
JavaScript ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์คํธ๋ฆผ ๊ตฌ์ฑ์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ด๊ณ ์ ์ง๋ณด์ ๊ฐ๋ฅํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฐ๋ ฅํ๊ณ ์ฐ์ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฒ์ ํ์ฉํ์ฌ ์ดํดํ๊ธฐ ์ฝ๊ณ ํ ์คํธ ๋ฐ ์ฌ์ฌ์ฉ์ด ์ฉ์ดํ ๋ณต์กํ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ๋ ๊น์ด ํ๊ณ ๋ค์๋ก, ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ๋ง์คํฐํ๋ ๊ฒ์ JavaScript ํดํท์์ ๊ท์คํ ์์ฐ์ด ๋ ๊ฒ์ ๋๋ค. ๋ค์ํ ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์คํธ๋ฆผ ๊ตฌ์ฑ ํจํด์ ์คํํ์ฌ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ํฌํ๋ก์ฐ์ ์ ์ฌ๋ ฅ์ ์ต๋ํ ๋ฐํํด ๋ณด์ธ์. ํญ์ ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ๊ณ ๋ คํ๊ณ ํน์ ์ฌ์ฉ ์ฌ๋ก์ ๊ฐ์ฅ ์ ํฉํ ๊ธฐ๋ฒ์ ์ ํํ๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์.